private void doOnLoad(
final EntityPersister persister,
final LoadEvent event,
final LoadEventListener.LoadType loadType) {
try {
final EventSource session = event.getSession();
final EntityKey keyToLoad = session.generateEntityKey( event.getEntityId(), persister );
if ( loadType.isNakedEntityReturned() ) {
//do not return a proxy!
//(this option indicates we are initializing a proxy)
event.setResult( load( event, persister, keyToLoad, loadType ) );
}
else {
//return a proxy if appropriate
if ( event.getLockMode() == LockMode.NONE ) {
event.setResult( proxyOrLoad( event, persister, keyToLoad, loadType ) );
}
else {
event.setResult( lockAndLoad( event, persister, keyToLoad, loadType, session ) );
}
}
}
catch (HibernateException e) {
LOG.unableToLoadCommand( e );
throw e;
}
}
// 1차 캐시?
private Object proxyOrLoad(
final LoadEvent event,
final EntityPersister persister,
final EntityKey keyToLoad,
final LoadEventListener.LoadType options) {
final EventSource session = event.getSession();
final SessionFactoryImplementor factory = session.getFactory();
final boolean traceEnabled = LOG.isTraceEnabled();
if ( traceEnabled ) {
LOG.tracev(
"Loading entity: {0}",
MessageHelper.infoString( persister, event.getEntityId(), factory )
);
}
final PersistenceContext persistenceContext = session.getPersistenceContextInternal();
final EntityMetamodel entityMetamodel = persister.getEntityMetamodel();
final boolean entityHasHibernateProxyFactory = entityMetamodel
.getTuplizer()
.getProxyFactory() != null;
// Check for the case where we can use the entity itself as a proxy
if ( options.isAllowProxyCreation()
&& entityMetamodel.getBytecodeEnhancementMetadata().isEnhancedForLazyLoading() ) {
// if there is already a managed entity instance associated with the PC, return it
final Object managed = persistenceContext.getEntity( keyToLoad );
if ( managed != null ) {
if ( options.isCheckDeleted() ) {
final EntityEntry entry = persistenceContext.getEntry( managed );
final Status status = entry.getStatus();
if ( status == Status.DELETED || status == Status.GONE ) {
return null;
}
}
return managed;
}
// if the entity defines a HibernateProxy factory, see if there is an
// existing proxy associated with the PC - and if so, use it
if ( entityHasHibernateProxyFactory ) {
final Object proxy = persistenceContext.getProxy( keyToLoad );
if ( proxy != null ) {
if( traceEnabled ) {
LOG.trace( "Entity proxy found in session cache" );
}
if ( LOG.isDebugEnabled() && ( (HibernateProxy) proxy ).getHibernateLazyInitializer().isUnwrap() ) {
LOG.debug( "Ignoring NO_PROXY to honor laziness" );
}
return persistenceContext.narrowProxy( proxy, persister, keyToLoad, null );
}
// specialized handling for entities with subclasses with a HibernateProxy factory
if ( entityMetamodel.hasSubclasses() ) {
// entities with subclasses that define a ProxyFactory can create a HibernateProxy
return createProxy( event, persister, keyToLoad, persistenceContext );
}
}
if ( !entityMetamodel.hasSubclasses() ) {
if ( keyToLoad.isBatchLoadable() ) {
// Add a batch-fetch entry into the queue for this entity
persistenceContext.getBatchFetchQueue().addBatchLoadableEntityKey( keyToLoad );
}
// This is the crux of HHH-11147
// create the (uninitialized) entity instance - has only id set
return persister.getBytecodeEnhancementMetadata().createEnhancedProxy( keyToLoad, true, session );
}
// If we get here, then the entity class has subclasses and there is no HibernateProxy factory.
// The entity will get loaded below.
}
else {
if ( persister.hasProxy() ) {
// look for a proxy
Object proxy = persistenceContext.getProxy( keyToLoad );
if ( proxy != null ) {
return returnNarrowedProxy( event, persister, keyToLoad, options, persistenceContext, proxy );
}
if ( options.isAllowProxyCreation() ) {
return createProxyIfNecessary( event, persister, keyToLoad, options, persistenceContext );
}
}
}
// return a newly loaded object
return load( event, persister, keyToLoad, options );
}
DefulatLoadEventListener.load
private Object load(
final LoadEvent event,
final EntityPersister persister,
final EntityKey keyToLoad,
final LoadEventListener.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);
}
final Object entity = doLoad( event, persister, keyToLoad, options ); // StatefulPersistenceContext.doLoad()
boolean isOptionalInstance = event.getInstanceToLoad() != null;
if ( entity == null && ( !options.isAllowNulls() || isOptionalInstance ) ) {
session
.getFactory()
.getEntityNotFoundDelegate()
.handleEntityNotFound( event.getEntityClassName(), event.getEntityId() );
}
else if ( isOptionalInstance && entity != event.getInstanceToLoad() ) {
throw new NonUniqueObjectException( event.getEntityId(), event.getEntityClassName() );
}
return entity;
}
StatefulPersistenceContext.doLoad() ⭐ ⭐
SessionLevelCache
SecondLevelCache
Datasource
private Object doLoad(
final LoadEvent event,
final EntityPersister persister,
final EntityKey keyToLoad,
final LoadEventListener.LoadType options) {
final EventSource session = event.getSession();
final boolean traceEnabled = LOG.isTraceEnabled();
if ( traceEnabled ) {
LOG.tracev(
"Attempting to resolve: {0}",
MessageHelper.infoString( persister, event.getEntityId(), session.getFactory() )
);
}
CacheEntityLoaderHelper.PersistenceContextEntry persistenceContextEntry = CacheEntityLoaderHelper.INSTANCE.loadFromSessionCache(
event,
keyToLoad,
options
);
Object entity = persistenceContextEntry.getEntity();
if ( entity != null ) {
return persistenceContextEntry.isManaged() ? entity : null;
}
entity = CacheEntityLoaderHelper.INSTANCE.loadFromSecondLevelCache( event, persister, keyToLoad );
if ( entity != null ) {
if ( traceEnabled ) {
LOG.tracev(
"Resolved object in second-level cache: {0}",
MessageHelper.infoString( persister, event.getEntityId(), session.getFactory() )
);
}
}
else {
if ( traceEnabled ) {
LOG.tracev(
"Object not resolved in any cache: {0}",
MessageHelper.infoString( persister, event.getEntityId(), session.getFactory() )
);
}
entity = loadFromDatasource( event, persister );
}
if ( entity != null && persister.hasNaturalIdentifier() ) {
final PersistenceContext persistenceContext = session.getPersistenceContextInternal();
final PersistenceContext.NaturalIdHelper naturalIdHelper = persistenceContext.getNaturalIdHelper();
naturalIdHelper.cacheNaturalIdCrossReferenceFromLoad(
persister,
event.getEntityId(),
naturalIdHelper.extractNaturalIdValues(
entity,
persister
)
);
}
return entity;
}
EventListnerGroupImpl.fireEventOnListener()
DefulatLoadEventListener.onLoad
DefulatLoadEventListener.doOnLoad
DefulatLoadEventListener.load
StatefulPersistenceContext.doLoad() ⭐ ⭐
AbstractEntityPersister.load() -> AbstractEntityPersister.doLoad()
AbstractLoadPlanBasedEntityLoader.load()
AbstractLoadPlanBasedLoader.executeLoad()
AbstractLoadPlanBasedLoader.executeQueryStatement()