下面列出了怎么用org.hibernate.engine.spi.EntityKey的API类实例代码及写法,或者点击链接到github查看源代码。
public ReactiveSubselectOneToManyLoader(
QueryableCollection persister,
String subquery,
Collection entityKeys,
QueryParameters queryParameters,
Map<String, int[]> namedParameterLocMap,
SessionFactoryImplementor factory,
LoadQueryInfluencers loadQueryInfluencers) throws MappingException {
super( persister, 1, subquery, factory, loadQueryInfluencers );
keys = new Serializable[ entityKeys.size() ];
Iterator iter = entityKeys.iterator();
int i=0;
while ( iter.hasNext() ) {
keys[i++] = ( (EntityKey) iter.next() ).getIdentifier();
}
this.namedParameters = queryParameters.getNamedParameters();
this.types = queryParameters.getFilteredPositionalParameterTypes();
this.values = queryParameters.getFilteredPositionalParameterValues();
this.namedParameterLocMap = namedParameterLocMap;
}
private void loadByDerivedIdentitySimplePkValue(
LoadEvent event,
LoadEventListener.LoadType options,
EntityPersister dependentPersister,
EmbeddedComponentType dependentIdType,
EntityPersister parentPersister) {
final EntityKey parentEntityKey = event.getSession().generateEntityKey( event.getEntityId(), parentPersister );
final Object parent = doLoad( event, parentPersister, parentEntityKey, options );
final Serializable dependent = (Serializable) dependentIdType.instantiate( parent, event.getSession() );
dependentIdType.setPropertyValues( dependent, new Object[] {parent}, dependentPersister.getEntityMode() );
final EntityKey dependentEntityKey = event.getSession().generateEntityKey( dependent, dependentPersister );
event.setEntityId( dependent );
event.setResult( doLoad( event, dependentPersister, dependentEntityKey, options ) );
}
public CompletionStage<Object[]> reactiveGetDatabaseSnapshot(Serializable id, EntityPersister persister)
throws HibernateException {
SessionImplementor session = (SessionImplementor) getSession();
final EntityKey key = session.generateEntityKey( id, persister );
final Object[] cached = entitySnapshotsByKey == null ? null : entitySnapshotsByKey.get( key );
if ( cached != null ) {
return CompletionStages.completedFuture( cached == NO_ROW ? null : cached );
}
else {
return ((ReactiveEntityPersister) persister).reactiveGetDatabaseSnapshot( id, session )
.thenApply( snapshot -> {
if ( entitySnapshotsByKey == null ) {
entitySnapshotsByKey = new HashMap<>(8);
}
entitySnapshotsByKey.put( key, snapshot == null ? NO_ROW : snapshot );
return snapshot;
} );
}
}
private void makeEntityCircularReferenceSafe(ReferenceCacheEntryImpl referenceCacheEntry,
EventSource session,
Object entity,
EntityKey entityKey) {
// make it circular-reference safe
final StatefulPersistenceContext statefulPersistenceContext = (StatefulPersistenceContext) session.getPersistenceContext();
if ( (entity instanceof ManagedEntity) ) {
statefulPersistenceContext.addReferenceEntry(
entity,
Status.READ_ONLY
);
}
else {
TwoPhaseLoad.addUninitializedCachedEntity(
entityKey,
entity,
referenceCacheEntry.getSubclassPersister(),
LockMode.NONE,
referenceCacheEntry.getVersion(),
session
);
}
statefulPersistenceContext.initializeNonLazyCollections();
}
/**
* Performs the load of an entity.
*
* @param event The initiating load request event
* @param persister The persister corresponding to the entity to be loaded
* @param keyToLoad The key of the entity to be loaded
* @param options The defined load options
*
* @return The loaded entity.
*/
private CompletionStage<Object> load( LoadEvent event, EntityPersister persister, EntityKey keyToLoad, LoadType options) {
final EventSource session = event.getSession();
if ( event.getInstanceToLoad() != null ) {
if ( session.getPersistenceContextInternal().getEntry( event.getInstanceToLoad() ) != null ) {
throw new PersistentObjectException(
"attempted to load into an instance that was already associated with the session: " +
MessageHelper.infoString( persister, event.getEntityId(), session.getFactory() ) );
}
persister.setIdentifier( event.getInstanceToLoad(), event.getEntityId(), session );
}
return doLoad( event, persister, keyToLoad, options )
.thenApply( optional -> {
boolean isOptionalInstance = event.getInstanceToLoad() != null;
if ( optional==null && ( !options.isAllowNulls() || isOptionalInstance ) ) {
throwEntityNotFound( session, event.getEntityClassName(), event.getEntityId() );
}
else if ( isOptionalInstance && optional != event.getInstanceToLoad() ) {
throw new NonUniqueObjectException( event.getEntityId(), event.getEntityClassName() );
}
return optional;
} );
}
public SubselectOneToManyLoader(
QueryableCollection persister,
String subquery,
Collection entityKeys,
QueryParameters queryParameters,
Map<String, int[]> namedParameterLocMap,
SessionFactoryImplementor factory,
LoadQueryInfluencers loadQueryInfluencers) throws MappingException {
super( persister, 1, subquery, factory, loadQueryInfluencers );
keys = new Serializable[ entityKeys.size() ];
Iterator iter = entityKeys.iterator();
int i=0;
while ( iter.hasNext() ) {
keys[i++] = ( (EntityKey) iter.next() ).getIdentifier();
}
this.namedParameters = queryParameters.getNamedParameters();
this.types = queryParameters.getFilteredPositionalParameterTypes();
this.values = queryParameters.getFilteredPositionalParameterValues();
this.namedParameterLocMap = namedParameterLocMap;
}
public SubselectCollectionLoader(
QueryableCollection persister,
String subquery,
Collection entityKeys,
QueryParameters queryParameters,
Map<String, int[]> namedParameterLocMap,
SessionFactoryImplementor factory,
LoadQueryInfluencers loadQueryInfluencers) throws MappingException {
super( persister, 1, subquery, factory, loadQueryInfluencers );
keys = new Serializable[ entityKeys.size() ];
Iterator iter = entityKeys.iterator();
int i=0;
while ( iter.hasNext() ) {
keys[i++] = ( (EntityKey) iter.next() ).getIdentifier();
}
this.namedParameters = queryParameters.getNamedParameters();
this.types = queryParameters.getFilteredPositionalParameterTypes();
this.values = queryParameters.getFilteredPositionalParameterValues();
this.namedParameterLocMap = namedParameterLocMap;
}
@Override
public Object read(ResultSet resultSet, ResultSetProcessingContext context) throws SQLException {
final EntityReferenceProcessingState processingState = getIdentifierResolutionContext( context );
final EntityKey entityKey = processingState.getEntityKey();
final Object entityInstance = context.getProcessingState( entityReturn ).getEntityInstance();
if ( context.shouldReturnProxies() ) {
final Object proxy = context.getSession().getPersistenceContext().proxyFor(
entityReturn.getEntityPersister(),
entityKey,
entityInstance
);
if ( proxy != entityInstance ) {
( (HibernateProxy) proxy ).getHibernateLazyInitializer().setImplementation( proxy );
return proxy;
}
}
return entityInstance;
}
private void handleMissingIdentifier(ResultSetProcessingContext context) {
if ( EntityFetch.class.isInstance( entityReference ) ) {
final EntityFetch fetch = (EntityFetch) entityReference;
final EntityType fetchedType = fetch.getFetchedType();
if ( ! fetchedType.isOneToOne() ) {
return;
}
final EntityReferenceProcessingState fetchOwnerState = context.getOwnerProcessingState( fetch );
if ( fetchOwnerState == null ) {
throw new IllegalStateException( "Could not locate fetch owner state" );
}
final EntityKey ownerEntityKey = fetchOwnerState.getEntityKey();
if ( ownerEntityKey != null ) {
context.getSession().getPersistenceContext().addNullProperty(
ownerEntityKey,
fetchedType.getPropertyName()
);
}
}
}
@Override
public Object readRow(ResultSet resultSet, ResultSetProcessingContextImpl context) throws SQLException {
final ResultSetProcessingContext.EntityReferenceProcessingState processingState =
rootReturnReader.getIdentifierResolutionContext( context );
// if the entity reference we are hydrating is a Return, it is possible that its EntityKey is
// supplied by the QueryParameter optional entity information
if ( context.shouldUseOptionalEntityInformation() && context.getQueryParameters().getOptionalId() != null ) {
final EntityKey entityKey = context.getSession().generateEntityKey(
context.getQueryParameters().getOptionalId(),
processingState.getEntityReference().getEntityPersister()
);
processingState.registerIdentifierHydratedForm( entityKey.getIdentifier() );
processingState.registerEntityKey( entityKey );
}
return super.readRow( resultSet, context );
}
private Object[] getDatabaseSnapshot(SessionImplementor session, EntityPersister persister, Serializable id) {
if ( persister.isSelectBeforeUpdateRequired() ) {
Object[] snapshot = session.getPersistenceContext()
.getDatabaseSnapshot( id, persister );
if ( snapshot == null ) {
//do we even really need this? the update will fail anyway....
if ( session.getFactory().getStatistics().isStatisticsEnabled() ) {
session.getFactory().getStatistics()
.optimisticFailure( persister.getEntityName() );
}
throw new StaleObjectStateException( persister.getEntityName(), id );
}
return snapshot;
}
// TODO: optimize away this lookup for entities w/o unsaved-value="undefined"
final EntityKey entityKey = session.generateEntityKey( id, persister );
return session.getPersistenceContext().getCachedDatabaseSnapshot( entityKey );
}
@Override
public Object getEntityUsingInterceptor(EntityKey key) throws HibernateException {
checkOpenOrWaitingForAutoClose();
// todo : should this get moved to PersistentContext?
// logically, is PersistentContext the "thing" to which an interceptor gets attached?
final Object result = persistenceContext.getEntity( key );
if ( result == null ) {
final Object newObject = getInterceptor().getEntity( key.getEntityName(), key.getIdentifier() );
if ( newObject != null ) {
lock( newObject, LockMode.NONE );
}
return newObject;
}
else {
return result;
}
}
@Override
public final void setReadOnly(boolean readOnly) {
errorIfReadOnlySettingNotAvailable();
// only update if readOnly is different from current setting
if ( this.readOnly != readOnly ) {
final EntityPersister persister = session.getFactory().getEntityPersister( entityName );
if ( !persister.isMutable() && !readOnly ) {
throw new IllegalStateException( "cannot make proxies [" + entityName + "#" + id + "] for immutable entities modifiable" );
}
this.readOnly = readOnly;
if ( initialized ) {
EntityKey key = generateEntityKeyOrNull( getIdentifier(), session, getEntityName() );
if ( key != null && session.getPersistenceContext().containsEntity( key ) ) {
session.getPersistenceContext().setReadOnly( target, readOnly );
}
}
}
}
@Override
public Object removeEntity(EntityKey key) {
final Object entity = entitiesByKey.remove( key );
final Iterator itr = entitiesByUniqueKey.values().iterator();
while ( itr.hasNext() ) {
if ( itr.next() == entity ) {
itr.remove();
}
}
// Clear all parent cache
parentsByChild.clear();
entitySnapshotsByKey.remove( key );
nullifiableEntityKeys.remove( key );
if( batchFetchQueue != null ) {
getBatchFetchQueue().removeBatchLoadableEntityKey(key);
getBatchFetchQueue().removeSubselect(key);
}
return entity;
}
@Override
public EntityEntry addEntity(
final Object entity,
final Status status,
final Object[] loadedState,
final EntityKey entityKey,
final Object version,
final LockMode lockMode,
final boolean existsInDatabase,
final EntityPersister persister,
final boolean disableVersionIncrement) {
addEntity( entityKey, entity );
return addEntry(
entity,
status,
loadedState,
null,
entityKey.getIdentifier(),
version,
lockMode,
existsInDatabase,
persister,
disableVersionIncrement
);
}
/**
* Attempts to load the entity from the second-level cache.
*
* @param event The load event
* @param persister The persister for the entity being requested for load
*
* @return The entity from the second-level cache, or null.
*/
private Object loadFromSecondLevelCache(
final LoadEvent event,
final EntityPersister persister,
final EntityKey entityKey) {
final SessionImplementor source = event.getSession();
final boolean useCache = persister.canReadFromCache()
&& source.getCacheMode().isGetEnabled()
&& event.getLockMode().lessThan( LockMode.READ );
if ( !useCache ) {
// we can't use cache here
return null;
}
final Object ce = getFromSharedCache( event, persister, source );
if ( ce == null ) {
// nothing was found in cache
return null;
}
return processCachedEntry( event, persister, ce, source, entityKey );
}
/**
* Add an uninitialized instance of an entity class, as a placeholder to ensure object
* identity. Must be called before <tt>postHydrate()</tt>.
*
* Create a "temporary" entry for a newly instantiated entity. The entity is uninitialized,
* but we need the mapping from id to instance in order to guarantee uniqueness.
*
* @param key The entity key
* @param object The entity instance
* @param persister The entity persister
* @param lockMode The lock mode
* @param session The Session
*/
public static void addUninitializedEntity(
final EntityKey key,
final Object object,
final EntityPersister persister,
final LockMode lockMode,
final SharedSessionContractImplementor session) {
session.getPersistenceContext().addEntity(
object,
Status.LOADING,
null,
key,
null,
lockMode,
true,
persister,
false
);
}
@Override
public Object[] getCachedDatabaseSnapshot(EntityKey key) {
final Object[] snapshot = entitySnapshotsByKey == null ? null : entitySnapshotsByKey.get( key );
if ( snapshot == NO_ROW ) {
throw new IllegalStateException(
"persistence context reported no row snapshot for "
+ infoString( key.getEntityName(), key.getIdentifier() )
);
}
return snapshot;
}
/**
* Attempts to locate the entity in the session-level cache.
* <p/>
* If allowed to return nulls, then if the entity happens to be found in
* the session cache, we check the entity type for proper handling
* of entity hierarchies.
* <p/>
* If checkDeleted was set to true, then if the entity is found in the
* session-level cache, it's current status within the session cache
* is checked to see if it has previously been scheduled for deletion.
*
* @param event The load event
* @param keyToLoad The EntityKey representing the entity to be loaded.
* @param options The load options.
*
* @return The entity from the session-level cache, or null.
*
* @throws HibernateException Generally indicates problems applying a lock-mode.
*/
protected Object loadFromSessionCache(
final LoadEvent event,
final EntityKey keyToLoad,
final LoadEventListener.LoadType options) throws HibernateException {
SessionImplementor session = event.getSession();
Object old = session.getEntityUsingInterceptor( keyToLoad );
if ( old != null ) {
// this object was already loaded
EntityEntry oldEntry = session.getPersistenceContext().getEntry( old );
if ( options.isCheckDeleted() ) {
Status status = oldEntry.getStatus();
if ( status == Status.DELETED || status == Status.GONE ) {
return REMOVED_ENTITY_MARKER;
}
}
if ( options.isAllowNulls() ) {
final EntityPersister persister = event.getSession()
.getFactory()
.getEntityPersister( keyToLoad.getEntityName() );
if ( !persister.isInstance( old ) ) {
return INCONSISTENT_RTN_CLASS_MARKER;
}
}
upgradeLock( old, oldEntry, event.getLockOptions(), event.getSession() );
}
return old;
}
private Object getProxyOrNull() {
final EntityKey entityKey = generateEntityKeyOrNull( getIdentifier(), session, getEntityName() );
if ( entityKey != null && session != null && session.isOpen() ) {
return session.getPersistenceContext().getProxy( entityKey );
}
return null;
}
/**
* Given a proxy, initialize it and/or narrow it provided either
* is necessary.
*
* @param event The initiating load request event
* @param persister The persister corresponding to the entity to be loaded
* @param keyToLoad The key of the entity to be loaded
* @param options The defined load options
* @param persistenceContext The originating session
* @param proxy The proxy to narrow
*
* @return The created/existing proxy
*/
private CompletionStage<Object> returnNarrowedProxy(
final LoadEvent event,
final EntityPersister persister,
final EntityKey keyToLoad,
final LoadEventListener.LoadType options,
final PersistenceContext persistenceContext,
final Object proxy) {
if ( LOG.isTraceEnabled() ) {
LOG.trace( "Entity proxy found in session cache" );
}
LazyInitializer li = ( (HibernateProxy) proxy ).getHibernateLazyInitializer();
if ( li.isUnwrap() ) {
return CompletionStages.completedFuture( li.getImplementation() );
}
CompletionStage<Object> implStage;
if ( !options.isAllowProxyCreation() ) {
implStage = load( event, persister, keyToLoad, options )
.thenApply( optional -> {
if ( optional == null ) {
event.getSession()
.getFactory()
.getEntityNotFoundDelegate()
.handleEntityNotFound( persister.getEntityName(), keyToLoad.getIdentifier() );
}
return optional;
} );
}
else {
implStage = CompletionStages.nullFuture();
}
return implStage.thenApply( impl -> persistenceContext.narrowProxy( proxy, persister, keyToLoad, impl ) );
}
/**
* If there is already a corresponding proxy associated with the
* persistence context, return it; otherwise create a proxy, associate it
* with the persistence context, and return the just-created proxy.
*
* @param event The initiating load request event
* @param persister The persister corresponding to the entity to be loaded
* @param keyToLoad The key of the entity to be loaded
* @param options The defined load options
* @param persistenceContext The originating session
*
* @return The created/existing proxy
*/
private Object createProxyIfNecessary(
final LoadEvent event,
final EntityPersister persister,
final EntityKey keyToLoad,
final LoadEventListener.LoadType options,
final PersistenceContext persistenceContext) {
Object existing = persistenceContext.getEntity( keyToLoad );
final boolean traceEnabled = LOG.isTraceEnabled();
if ( existing != null ) {
// return existing object or initialized proxy (unless deleted)
if ( traceEnabled ) {
LOG.trace( "Entity found in session cache" );
}
if ( options.isCheckDeleted() ) {
EntityEntry entry = persistenceContext.getEntry( existing );
Status status = entry.getStatus();
if ( status == Status.DELETED || status == Status.GONE ) {
return null;
}
}
return existing;
}
if ( traceEnabled ) {
LOG.trace( "Creating new proxy for entity" );
}
return createProxy( event, persister, keyToLoad, persistenceContext );
}
private Object createProxy(
LoadEvent event,
EntityPersister persister,
EntityKey keyToLoad,
PersistenceContext persistenceContext) {
// return new uninitialized proxy
Object proxy = persister.createProxy( event.getEntityId(), event.getSession() );
persistenceContext.getBatchFetchQueue().addBatchLoadableEntityKey( keyToLoad );
persistenceContext.addProxy( keyToLoad, proxy );
return proxy;
}
private boolean isCurrentRowForSameEntity(
final EntityKey keyToRead,
final int persisterIndex,
final ResultSet resultSet,
final SharedSessionContractImplementor session) throws SQLException {
EntityKey currentRowKey = getKeyFromResultSet(
persisterIndex, getEntityPersisters()[persisterIndex], null, resultSet, session
);
return keyToRead.equals( currentRowKey );
}
private Object convertCacheReferenceEntryToEntity(
ReferenceCacheEntryImpl referenceCacheEntry,
EventSource session,
EntityKey entityKey) {
final Object entity = referenceCacheEntry.getReference();
if ( entity == null ) {
throw new IllegalStateException(
"Reference cache entry contained null : " + referenceCacheEntry.toString());
}
else {
makeEntityCircularReferenceSafe( referenceCacheEntry, session, entity, entityKey );
return entity;
}
}
private static Set[] transpose(List keys) {
Set[] result = new Set[( (EntityKey[]) keys.get( 0 ) ).length];
for ( int j = 0; j < result.length; j++ ) {
result[j] = new HashSet( keys.size() );
for ( Object key : keys ) {
result[j].add( ( (EntityKey[]) key )[j] );
}
}
return result;
}
private void createSubselects(List keys, QueryParameters queryParameters, SharedSessionContractImplementor session) {
if ( keys.size() > 1 ) { //if we only returned one entity, query by key is more efficient
Set[] keySets = transpose( keys );
Map namedParameterLocMap = buildNamedParameterLocMap( queryParameters );
final Loadable[] loadables = getEntityPersisters();
final String[] aliases = getAliases();
final String subselectQueryString = SubselectFetch.createSubselectFetchQueryFragment( queryParameters );
for ( Object key : keys ) {
final EntityKey[] rowKeys = (EntityKey[]) key;
for ( int i = 0; i < rowKeys.length; i++ ) {
if ( rowKeys[i] != null && loadables[i].hasSubselectLoadableCollections() ) {
SubselectFetch subselectFetch = new SubselectFetch(
subselectQueryString,
aliases[i],
loadables[i],
queryParameters,
keySets[i],
namedParameterLocMap
);
session.getPersistenceContext()
.getBatchFetchQueue()
.addSubselect( rowKeys[i], subselectFetch );
}
}
}
}
}
/**
* If there is already a corresponding proxy associated with the
* persistence context, return it; otherwise create a proxy, associate it
* with the persistence context, and return the just-created proxy.
*
* @param event The initiating load request event
* @param persister The persister corresponding to the entity to be loaded
* @param keyToLoad The key of the entity to be loaded
* @param options The defined load options
* @param persistenceContext The originating session
*
* @return The created/existing proxy
*/
private Object createProxyIfNecessary(
final LoadEvent event,
final EntityPersister persister,
final EntityKey keyToLoad,
final LoadEventListener.LoadType options,
final PersistenceContext persistenceContext) {
Object existing = persistenceContext.getEntity( keyToLoad );
if ( existing != null ) {
// return existing object or initialized proxy (unless deleted)
if ( traceEnabled ) {
LOG.trace( "Entity found in session cache" );
}
if ( options.isCheckDeleted() ) {
EntityEntry entry = persistenceContext.getEntry( existing );
Status status = entry.getStatus();
if ( status == Status.DELETED || status == Status.GONE ) {
return null;
}
}
return existing;
}
if ( traceEnabled ) {
LOG.trace( "Creating new proxy for entity" );
}
// return new uninitialized proxy
Object proxy = persister.createProxy( event.getEntityId(), event.getSession() );
persistenceContext.getBatchFetchQueue().addBatchLoadableEntityKey( keyToLoad );
persistenceContext.addProxy( keyToLoad, proxy );
return proxy;
}
/**
* The entity instance is already in the session cache
*/
private void instanceAlreadyLoaded(
final ResultSet rs,
final int i,
final Loadable persister,
final EntityKey key,
final Object object,
final LockMode requestedLockMode,
final SharedSessionContractImplementor session)
throws HibernateException, SQLException {
if ( !persister.isInstance( object ) ) {
throw new WrongClassException(
"loaded object was of wrong class " + object.getClass(),
key.getIdentifier(),
persister.getEntityName()
);
}
if ( LockMode.NONE != requestedLockMode && upgradeLocks() ) { //no point doing this if NONE was requested
final EntityEntry entry = session.getPersistenceContext().getEntry( object );
if ( entry.getLockMode().lessThan( requestedLockMode ) ) {
//we only check the version when _upgrading_ lock modes
if ( persister.isVersioned() ) {
checkVersion( i, persister, key.getIdentifier(), object, rs, session );
}
//we need to upgrade the lock mode to the mode requested
entry.setLockMode( requestedLockMode );
}
}
}
/**
* If the class to be loaded has been configured with a cache, then lock
* given id in that cache and then perform the load.
*
* @param event The initiating load request event
* @param persister The persister corresponding to the entity to be loaded
* @param keyToLoad The key of the entity to be loaded
* @param options The defined load options
* @param source The originating session
*
* @return The loaded entity
*
* @throws HibernateException
*/
private Object lockAndLoad(
final LoadEvent event,
final EntityPersister persister,
final EntityKey keyToLoad,
final LoadEventListener.LoadType options,
final SessionImplementor source) {
SoftLock lock = null;
final Object ck;
final EntityDataAccess cache = persister.getCacheAccessStrategy();
if ( persister.canWriteToCache() ) {
ck = cache.generateCacheKey(
event.getEntityId(),
persister,
source.getFactory(),
source.getTenantIdentifier()
);
lock = persister.getCacheAccessStrategy().lockItem( source, ck, null );
}
else {
ck = null;
}
Object entity;
try {
entity = load( event, persister, keyToLoad, options );
}
finally {
if ( persister.canWriteToCache() ) {
cache.unlockItem( source, ck, lock );
}
}
return event.getSession().getPersistenceContext().proxyFor( persister, keyToLoad, entity );
}