📄 defaultloadeventlistener.java
字号:
return proxy;
}
/**
* Coordinates the efforts to load a given entity. First, an attempt is
* made to load the entity from the session-level cache. If not found there,
* an attempt is made to locate it in second-level cache. Lastly, an
* attempt is made to load it directly from the datasource.
*
* @return The loaded entity.
* @throws HibernateException
*/
protected Object doLoad(
final LoadEvent event,
final EntityPersister persister,
final EntityKey keyToLoad,
final LoadEventListener.LoadType options)
throws HibernateException {
if ( log.isTraceEnabled() ) {
log.trace(
"attempting to resolve: " +
MessageHelper.infoString( persister, event.getEntityId(), event.getSession().getFactory() )
);
}
Object entity = loadFromSessionCache(event, keyToLoad, options);
if ( entity != null ) {
if ( log.isTraceEnabled() ) {
log.trace(
"resolved object in session cache: " +
MessageHelper.infoString( persister, event.getEntityId(), event.getSession().getFactory() )
);
}
return entity;
}
// Entity not found in session; before going any further, see if we
// already determined that this entity does not exist
/*if ( event.getSession().getPersistenceContext().isNonExistant(keyToLoad) ) {
if ( log.isTraceEnabled() ) log.trace("entity does not exist");
return null;
}*/
entity = loadFromSecondLevelCache(event, persister, options);
if ( entity != null ) {
if ( log.isTraceEnabled() ) {
log.trace(
"resolved object in second-level cache: " +
MessageHelper.infoString( persister, event.getEntityId(), event.getSession().getFactory() )
);
}
return entity;
}
if ( log.isTraceEnabled() ) {
log.trace(
"object not resolved in any cache: " +
MessageHelper.infoString( persister, event.getEntityId(), event.getSession().getFactory() )
);
}
return loadFromDatasource(event, persister, keyToLoad, options);
}
/**
* Performs the process of loading an entity from the configured
* underlying datasource.
*
* @return The object loaded from the datasource, or null if not found.
* @throws HibernateException
*/
protected Object loadFromDatasource(
final LoadEvent event,
final EntityPersister persister,
final EntityKey keyToLoad,
final LoadEventListener.LoadType options)
throws HibernateException {
final SessionImplementor source = event.getSession();
Object entity = persister.load(
event.getEntityId(),
event.getInstanceToLoad(),
event.getLockMode(),
source
);
/*if ( entity == null ) {
//remember it doesn't exist, in case of next time
source.getPersistenceContext().addNonExistantEntityKey(keyToLoad);
}*/
if ( event.isAssociationFetch() && source.getFactory().getStatistics().isStatisticsEnabled() ) {
source.getFactory().getStatisticsImplementor().fetchEntity( event.getEntityClassName() );
}
return entity;
}
/**
* Attempts to locate the entity in the session-level cache. 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.
*
* @return The entity from the session-level cache, or null.
* @throws HibernateException
*/
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() ) {
throwObjectDeletedIfNecessary( event, oldEntry );
}
upgradeLock( old, oldEntry, event.getLockMode(), session );
}
return old;
}
private void throwObjectDeletedIfNecessary(LoadEvent event, EntityEntry oldEntry) {
Status status = oldEntry.getStatus();
if ( status == Status.DELETED || status == Status.GONE ) {
throw new ObjectDeletedException(
"The object with that id was deleted",
event.getEntityId(),
event.getEntityClassName()
);
}
}
/**
* Attempts to load the entity from the second-level cache.
*
* @return The entity from the second-level cache, or null.
* @throws HibernateException
*/
protected Object loadFromSecondLevelCache(
final LoadEvent event,
final EntityPersister persister,
final LoadEventListener.LoadType options)
throws HibernateException {
final SessionImplementor source = event.getSession();
final boolean useCache = persister.hasCache() &&
source.getCacheMode().isGetEnabled() &&
event.getLockMode().lessThan(LockMode.READ);
if (useCache) {
final SessionFactoryImplementor factory = source.getFactory();
final CacheKey ck = new CacheKey(
event.getEntityId(),
persister.getIdentifierType(),
persister.getRootEntityName(),
source.getEntityMode(),
source.getFactory()
);
Object ce = persister.getCache()
.get( ck, source.getTimestamp() );
if ( factory.getStatistics().isStatisticsEnabled() ) {
if (ce==null) {
factory.getStatisticsImplementor().secondLevelCacheMiss(
persister.getCache().getRegionName()
);
}
else {
factory.getStatisticsImplementor().secondLevelCacheHit(
persister.getCache().getRegionName()
);
}
}
if ( ce != null ) {
CacheEntry entry = (CacheEntry) persister.getCacheEntryStructure()
.destructure(ce, factory);
// Entity was found in second-level cache...
return assembleCacheEntry(
entry,
event.getEntityId(),
persister,
event
);
}
}
return null;
}
private Object assembleCacheEntry(
final CacheEntry entry,
final Serializable id,
final EntityPersister persister,
final LoadEvent event)
throws HibernateException {
final Object optionalObject = event.getInstanceToLoad();
final EventSource session = event.getSession();
final SessionFactoryImplementor factory = session.getFactory();
if ( log.isTraceEnabled() ) {
log.trace(
"assembling entity from second-level cache: " +
MessageHelper.infoString( persister, id, factory )
);
}
EntityPersister subclassPersister = factory.getEntityPersister( entry.getSubclass() );
Object result = optionalObject == null ?
session.instantiate( subclassPersister, id ) : optionalObject;
// make it circular-reference safe
TwoPhaseLoad.addUninitializedCachedEntity(
new EntityKey( id, subclassPersister, session.getEntityMode() ),
result,
subclassPersister,
LockMode.NONE,
entry.areLazyPropertiesUnfetched(),
entry.getVersion(),
session
);
Type[] types = subclassPersister.getPropertyTypes();
Object[] values = entry.assemble( result, id, subclassPersister, session.getInterceptor(), session ); // intializes result by side-effect
TypeFactory.deepCopy(
values,
types,
subclassPersister.getPropertyUpdateability(),
values,
session
);
Object version = Versioning.getVersion( values, subclassPersister );
if ( log.isTraceEnabled() ) log.trace( "Cached Version: " + version );
final PersistenceContext persistenceContext = session.getPersistenceContext();
persistenceContext.addEntry(
result,
Status.MANAGED,
values,
null,
id,
version,
LockMode.NONE,
true,
subclassPersister,
false,
entry.areLazyPropertiesUnfetched()
);
subclassPersister.afterInitialize( result, entry.areLazyPropertiesUnfetched(), session );
persistenceContext.initializeNonLazyCollections();
// upgrade the lock if necessary:
//lock(result, lockMode);
//PostLoad is needed for EJB3
//TODO: reuse the PostLoadEvent...
PostLoadEvent postLoadEvent = new PostLoadEvent(session).setEntity(result)
.setId(id).setPersister(persister);
PostLoadEventListener[] listeners = session.getListeners().getPostLoadEventListeners();
for ( int i = 0; i < listeners.length; i++ ) {
listeners[i].onPostLoad(postLoadEvent);
}
return result;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -