diff --git a/hibernate-core/src/main/java/org/hibernate/event/internal/DefaultLoadEventListener.java b/hibernate-core/src/main/java/org/hibernate/event/internal/DefaultLoadEventListener.java index 08510f42e0..a23735aad0 100644 --- a/hibernate-core/src/main/java/org/hibernate/event/internal/DefaultLoadEventListener.java +++ b/hibernate-core/src/main/java/org/hibernate/event/internal/DefaultLoadEventListener.java @@ -615,7 +615,7 @@ public class DefaultLoadEventListener extends AbstractLockUpgradeEventListener i } else { entity = convertCacheReferenceEntryToEntity( (ReferenceCacheEntryImpl) entry, - event.getEntityId(), persister, event.getSession(), entityKey ); + event.getEntityId(), persister, event.getSession(), entityKey, event ); } } else { @@ -638,7 +638,8 @@ public class DefaultLoadEventListener extends AbstractLockUpgradeEventListener i Serializable entityId, EntityPersister persister, EventSource session, - EntityKey entityKey) { + EntityKey entityKey, + LoadEvent loadEvent) { final Object entity = referenceCacheEntry.getReference(); if ( entity == null ) { @@ -651,15 +652,15 @@ public class DefaultLoadEventListener extends AbstractLockUpgradeEventListener i EventListenerGroup evenListenerGroup = getEvenListenerGroup(session); if(!evenListenerGroup.isEmpty()) { - postLoad(session, evenListenerGroup.listeners(), entity, entityId, persister); + postLoad(session, evenListenerGroup.listeners(), entity, entityId, persister, loadEvent); } return entity; } } private void postLoad(EventSource session, Iterable listeners, - Object entity, Serializable entityId, EntityPersister persister) { - PostLoadEvent postLoadEvent = new PostLoadEvent(session) + Object entity, Serializable entityId, EntityPersister persister, LoadEvent event) { + PostLoadEvent postLoadEvent = event.getPostLoadEvent() .setEntity(entity) .setId(entityId) .setPersister(persister); @@ -788,7 +789,7 @@ public class DefaultLoadEventListener extends AbstractLockUpgradeEventListener i persistenceContext.initializeNonLazyCollections(); //PostLoad is needed for EJB3 - PostLoadEvent postLoadEvent = new PostLoadEvent( session ) + PostLoadEvent postLoadEvent = event.getPostLoadEvent() .setEntity( entity ) .setId( entityId ) .setPersister( persister ); @@ -885,7 +886,7 @@ public class DefaultLoadEventListener extends AbstractLockUpgradeEventListener i //PostLoad is needed for EJB3 //TODO: reuse the PostLoadEvent... - PostLoadEvent postLoadEvent = new PostLoadEvent( session ) + PostLoadEvent postLoadEvent = event.getPostLoadEvent() .setEntity( result ) .setId( id ) .setPersister( persister ); diff --git a/hibernate-core/src/main/java/org/hibernate/event/spi/LoadEvent.java b/hibernate-core/src/main/java/org/hibernate/event/spi/LoadEvent.java index aecaa8004e..017f23e89a 100644 --- a/hibernate-core/src/main/java/org/hibernate/event/spi/LoadEvent.java +++ b/hibernate-core/src/main/java/org/hibernate/event/spi/LoadEvent.java @@ -45,6 +45,7 @@ public class LoadEvent extends AbstractEvent { private LockOptions lockOptions; private boolean isAssociationFetch; private Object result; + private PostLoadEvent postLoadEvent; public LoadEvent(Serializable entityId, Object instanceToLoad, EventSource source) { this( entityId, null, instanceToLoad, DEFAULT_LOCK_OPTIONS, false, source ); @@ -104,6 +105,7 @@ public class LoadEvent extends AbstractEvent { this.instanceToLoad = instanceToLoad; this.lockOptions = lockOptions; this.isAssociationFetch = isAssociationFetch; + this.postLoadEvent = new PostLoadEvent(source); } public Serializable getEntityId() { @@ -180,4 +182,12 @@ public class LoadEvent extends AbstractEvent { public void setResult(Object result) { this.result = result; } + + public PostLoadEvent getPostLoadEvent() { + return postLoadEvent; + } + + public void setPostLoadEvent(PostLoadEvent postLoadEvent) { + this.postLoadEvent = postLoadEvent; + } } diff --git a/hibernate-core/src/main/java/org/hibernate/internal/SessionImpl.java b/hibernate-core/src/main/java/org/hibernate/internal/SessionImpl.java index a44c21f163..1f5ac20de0 100644 --- a/hibernate-core/src/main/java/org/hibernate/internal/SessionImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/internal/SessionImpl.java @@ -205,6 +205,7 @@ public final class SessionImpl extends AbstractSessionImpl implements EventSourc private transient ExceptionMapper exceptionMapper; private transient ManagedFlushChecker managedFlushChecker; private transient AfterCompletionAction afterCompletionAction; + private transient LoadEvent loadEvent; //cached LoadEvent instance /** * Constructor used for openSession(...) processing, as well as construction @@ -936,8 +937,26 @@ public final class SessionImpl extends AbstractSessionImpl implements EventSourc @Override public void load(Object object, Serializable id) throws HibernateException { - LoadEvent event = new LoadEvent( id, object, this ); + LoadEvent event = loadEvent; + loadEvent = null; + if(event == null) { + event = new LoadEvent( id, object, this ); + } else { + event.setEntityClassName(null); + event.setEntityId(id); + event.setInstanceToLoad(object); + event.setLockMode(LoadEvent.DEFAULT_LOCK_MODE); + event.setLockScope(LoadEvent.DEFAULT_LOCK_OPTIONS.getScope()); + event.setLockTimeout(LoadEvent.DEFAULT_LOCK_OPTIONS.getTimeOut()); + } fireLoad( event, LoadEventListener.RELOAD ); + if(loadEvent == null) { + event.setEntityClassName(null); + event.setEntityId(null); + event.setInstanceToLoad(null); + event.setResult(null); + loadEvent = event; + } } @Override @@ -971,10 +990,28 @@ public final class SessionImpl extends AbstractSessionImpl implements EventSourc EntityPersister persister = getFactory().getEntityPersister( entityName ); LOG.debugf( "Initializing proxy: %s", MessageHelper.infoString( persister, id, getFactory() ) ); } - - LoadEvent event = new LoadEvent( id, entityName, true, this ); + LoadEvent event = loadEvent; + loadEvent = null; + if(event == null) { + event = new LoadEvent( id, entityName, true, this ); + } else { + event.setEntityClassName(entityName); + event.setEntityId(id); + event.setInstanceToLoad(null); + event.setLockMode(LoadEvent.DEFAULT_LOCK_MODE); + event.setLockScope(LoadEvent.DEFAULT_LOCK_OPTIONS.getScope()); + event.setLockTimeout(LoadEvent.DEFAULT_LOCK_OPTIONS.getTimeOut()); + } fireLoad( event, LoadEventListener.IMMEDIATE_LOAD ); - return event.getResult(); + Object result = event.getResult(); + if(loadEvent == null) { + event.setEntityClassName(null); + event.setEntityId(null); + event.setInstanceToLoad(null); + event.setResult(null); + loadEvent = event; + } + return result; } @Override @@ -986,12 +1023,32 @@ public final class SessionImpl extends AbstractSessionImpl implements EventSourc : eager ? LoadEventListener.INTERNAL_LOAD_EAGER : LoadEventListener.INTERNAL_LOAD_LAZY; - LoadEvent event = new LoadEvent( id, entityName, true, this ); - fireLoad( event, type ); - if ( !nullable ) { - UnresolvableObjectException.throwIfNull( event.getResult(), id, entityName ); + + LoadEvent event = loadEvent; + loadEvent = null; + if(event == null) { + event = new LoadEvent( id, entityName, true, this ); + } else { + event.setEntityClassName(entityName); + event.setEntityId(id); + event.setInstanceToLoad(null); + event.setLockMode(LoadEvent.DEFAULT_LOCK_MODE); + event.setLockScope(LoadEvent.DEFAULT_LOCK_OPTIONS.getScope()); + event.setLockTimeout(LoadEvent.DEFAULT_LOCK_OPTIONS.getTimeOut()); } - return event.getResult(); + fireLoad( event, type ); + Object result = event.getResult(); + if ( !nullable ) { + UnresolvableObjectException.throwIfNull(result, id, entityName ); + } + if(loadEvent == null) { + event.setEntityClassName(null); + event.setEntityId(null); + event.setInstanceToLoad(null); + event.setResult(null); + loadEvent = event; + } + return result; } @Override