HHH-13478 Micro optimisations in DefaultLoadEventListener

This commit is contained in:
Sanne Grinovero 2019-06-24 22:58:36 +01:00
parent 035657c9ec
commit 304a34f6d8
1 changed files with 46 additions and 32 deletions

View File

@ -19,6 +19,7 @@ import org.hibernate.cache.spi.access.SoftLock;
import org.hibernate.engine.spi.EntityEntry;
import org.hibernate.engine.spi.EntityKey;
import org.hibernate.engine.spi.PersistenceContext;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.engine.spi.Status;
import org.hibernate.event.spi.EventSource;
@ -31,6 +32,8 @@ import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.pretty.MessageHelper;
import org.hibernate.proxy.HibernateProxy;
import org.hibernate.proxy.LazyInitializer;
import org.hibernate.stat.spi.StatisticsImplementor;
import org.hibernate.tuple.IdentifierProperty;
import org.hibernate.tuple.entity.EntityMetamodel;
import org.hibernate.type.EmbeddedComponentType;
import org.hibernate.type.EntityType;
@ -71,13 +74,14 @@ public class DefaultLoadEventListener implements LoadEventListener {
doOnLoad( persister, event, loadType );
}
protected EntityPersister getPersister( final LoadEvent event ) {
if ( event.getInstanceToLoad() != null ) {
protected EntityPersister getPersister(final LoadEvent event) {
final Object instanceToLoad = event.getInstanceToLoad();
if ( instanceToLoad != null ) {
//the load() which takes an entity does not pass an entityName
event.setEntityClassName( event.getInstanceToLoad().getClass().getName() );
event.setEntityClassName( instanceToLoad.getClass().getName() );
return event.getSession().getEntityPersister(
null,
event.getInstanceToLoad()
instanceToLoad
);
}
else {
@ -91,7 +95,8 @@ public class DefaultLoadEventListener implements LoadEventListener {
final LoadEventListener.LoadType loadType) {
try {
final EntityKey keyToLoad = event.getSession().generateEntityKey( event.getEntityId(), persister );
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)
@ -103,7 +108,7 @@ public class DefaultLoadEventListener implements LoadEventListener {
event.setResult( proxyOrLoad( event, persister, keyToLoad, loadType ) );
}
else {
event.setResult( lockAndLoad( event, persister, keyToLoad, loadType, event.getSession() ) );
event.setResult( lockAndLoad( event, persister, keyToLoad, loadType, session ) );
}
}
}
@ -121,14 +126,16 @@ public class DefaultLoadEventListener implements LoadEventListener {
// we may have the kooky jpa requirement of allowing find-by-id where
// "id" is the "simple pk value" of a dependent objects parent. This
// is part of its generally goofy "derived identity" "feature"
if ( persister.getEntityMetamodel().getIdentifierProperty().isEmbedded() ) {
final IdentifierProperty identifierProperty = persister.getEntityMetamodel().getIdentifierProperty();
if ( identifierProperty.isEmbedded() ) {
final EmbeddedComponentType dependentIdType =
(EmbeddedComponentType) persister.getEntityMetamodel().getIdentifierProperty().getType();
(EmbeddedComponentType) identifierProperty.getType();
if ( dependentIdType.getSubtypes().length == 1 ) {
final Type singleSubType = dependentIdType.getSubtypes()[0];
if ( singleSubType.isEntityType() ) {
final EntityType dependentParentType = (EntityType) singleSubType;
final Type dependentParentIdType = dependentParentType.getIdentifierOrUniqueKeyType( event.getSession().getFactory() );
final SessionFactoryImplementor factory = event.getSession().getFactory();
final Type dependentParentIdType = dependentParentType.getIdentifierOrUniqueKeyType( factory );
if ( dependentParentIdType.getReturnedClass().isInstance( event.getEntityId() ) ) {
// yep that's what we have...
loadByDerivedIdentitySimplePkValue(
@ -136,7 +143,7 @@ public class DefaultLoadEventListener implements LoadEventListener {
loadType,
persister,
dependentIdType,
event.getSession().getFactory().getMetamodel().entityPersister( dependentParentType.getAssociatedEntityName() )
factory.getMetamodel().entityPersister( dependentParentType.getAssociatedEntityName() )
);
return;
}
@ -155,12 +162,13 @@ public class DefaultLoadEventListener implements LoadEventListener {
EntityPersister dependentPersister,
EmbeddedComponentType dependentIdType,
EntityPersister parentPersister) {
final EntityKey parentEntityKey = event.getSession().generateEntityKey( event.getEntityId(), parentPersister );
final EventSource session = event.getSession();
final EntityKey parentEntityKey = session.generateEntityKey( event.getEntityId(), parentPersister );
final Object parent = doLoad( event, parentPersister, parentEntityKey, options );
final Serializable dependent = (Serializable) dependentIdType.instantiate( parent, event.getSession() );
final Serializable dependent = (Serializable) dependentIdType.instantiate( parent, session );
dependentIdType.setPropertyValues( dependent, new Object[] {parent}, dependentPersister.getEntityMode() );
final EntityKey dependentEntityKey = event.getSession().generateEntityKey( dependent, dependentPersister );
final EntityKey dependentEntityKey = session.generateEntityKey( dependent, dependentPersister );
event.setEntityId( dependent );
event.setResult( doLoad( event, dependentPersister, dependentEntityKey, options ) );
@ -231,17 +239,19 @@ public class DefaultLoadEventListener implements LoadEventListener {
final EntityKey keyToLoad,
final LoadEventListener.LoadType options) {
final EventSource session = event.getSession();
final SessionFactoryImplementor factory = session.getFactory();
if ( LOG.isTraceEnabled() ) {
LOG.tracev(
"Loading entity: {0}",
MessageHelper.infoString( persister, event.getEntityId(), event.getSession().getFactory() )
MessageHelper.infoString( persister, event.getEntityId(), factory )
);
}
final PersistenceContext persistenceContext = event.getSession().getPersistenceContextInternal();
final PersistenceContext persistenceContext = session.getPersistenceContextInternal();
final boolean allowBytecodeProxy = event.getSession()
.getFactory()
final boolean allowBytecodeProxy = factory
.getSessionFactoryOptions()
.isEnhancementAsProxyEnabled();
@ -303,7 +313,7 @@ public class DefaultLoadEventListener implements LoadEventListener {
// This is the crux of HHH-11147
// create the (uninitialized) entity instance - has only id set
return persister.getBytecodeEnhancementMetadata().createEnhancedProxy( keyToLoad, true, event.getSession() );
return persister.getBytecodeEnhancementMetadata().createEnhancedProxy( keyToLoad, true, session );
}
else {
if ( persister.hasProxy() ) {
@ -388,9 +398,10 @@ public class DefaultLoadEventListener implements LoadEventListener {
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 ( LOG.isTraceEnabled() ) {
if ( traceEnabled ) {
LOG.trace( "Entity found in session cache" );
}
if ( options.isCheckDeleted() ) {
@ -402,7 +413,7 @@ public class DefaultLoadEventListener implements LoadEventListener {
}
return existing;
}
if ( LOG.isTraceEnabled() ) {
if ( traceEnabled ) {
LOG.trace( "Creating new proxy for entity" );
}
return createProxy( event, persister, keyToLoad, persistenceContext );
@ -441,14 +452,15 @@ public class DefaultLoadEventListener implements LoadEventListener {
SoftLock lock = null;
final Object ck;
final EntityDataAccess cache = persister.getCacheAccessStrategy();
if ( persister.canWriteToCache() ) {
final boolean canWriteToCache = persister.canWriteToCache();
if ( canWriteToCache ) {
ck = cache.generateCacheKey(
event.getEntityId(),
persister,
source.getFactory(),
source.getTenantIdentifier()
);
lock = persister.getCacheAccessStrategy().lockItem( source, ck, null );
lock = cache.lockItem( source, ck, null );
}
else {
ck = null;
@ -459,12 +471,12 @@ public class DefaultLoadEventListener implements LoadEventListener {
entity = load( event, persister, keyToLoad, options );
}
finally {
if ( persister.canWriteToCache() ) {
if ( canWriteToCache ) {
cache.unlockItem( source, ck, lock );
}
}
return event.getSession().getPersistenceContextInternal().proxyFor( persister, keyToLoad, entity );
return source.getPersistenceContextInternal().proxyFor( persister, keyToLoad, entity );
}
@ -488,7 +500,8 @@ public class DefaultLoadEventListener implements LoadEventListener {
final LoadEventListener.LoadType options) {
final EventSource session = event.getSession();
if ( LOG.isTraceEnabled() ) {
final boolean traceEnabled = LOG.isTraceEnabled();
if ( traceEnabled ) {
LOG.tracev(
"Attempting to resolve: {0}",
MessageHelper.infoString( persister, event.getEntityId(), session.getFactory() )
@ -508,7 +521,7 @@ public class DefaultLoadEventListener implements LoadEventListener {
entity = CacheEntityLoaderHelper.INSTANCE.loadFromSecondLevelCache( event, persister, keyToLoad );
if ( entity != null ) {
if ( LOG.isTraceEnabled() ) {
if ( traceEnabled ) {
LOG.tracev(
"Resolved object in second-level cache: {0}",
MessageHelper.infoString( persister, event.getEntityId(), session.getFactory() )
@ -516,7 +529,7 @@ public class DefaultLoadEventListener implements LoadEventListener {
}
}
else {
if ( LOG.isTraceEnabled() ) {
if ( traceEnabled ) {
LOG.tracev(
"Object not resolved in any cache: {0}",
MessageHelper.infoString( persister, event.getEntityId(), session.getFactory() )
@ -527,17 +540,17 @@ public class DefaultLoadEventListener implements LoadEventListener {
if ( entity != null && persister.hasNaturalIdentifier() ) {
final PersistenceContext persistenceContext = session.getPersistenceContextInternal();
persistenceContext.getNaturalIdHelper().cacheNaturalIdCrossReferenceFromLoad(
final PersistenceContext.NaturalIdHelper naturalIdHelper = persistenceContext.getNaturalIdHelper();
naturalIdHelper.cacheNaturalIdCrossReferenceFromLoad(
persister,
event.getEntityId(),
persistenceContext.getNaturalIdHelper().extractNaturalIdValues(
naturalIdHelper.extractNaturalIdValues(
entity,
persister
)
);
}
return entity;
}
@ -561,8 +574,9 @@ public class DefaultLoadEventListener implements LoadEventListener {
event.getSession()
);
if ( event.isAssociationFetch() && event.getSession().getFactory().getStatistics().isStatisticsEnabled() ) {
event.getSession().getFactory().getStatistics().fetchEntity( event.getEntityClassName() );
final StatisticsImplementor statistics = event.getSession().getFactory().getStatistics();
if ( event.isAssociationFetch() && statistics.isStatisticsEnabled() ) {
statistics.fetchEntity( event.getEntityClassName() );
}
return entity;