HHH-10302 Cache the LoadEvent and PostLoadEvent to reduce allocations

This commit is contained in:
Stuart Douglas 2015-11-16 09:27:48 +11:00 committed by Sanne Grinovero
parent f4e58d342d
commit 85db76431c
3 changed files with 84 additions and 16 deletions

View File

@ -615,7 +615,7 @@ public class DefaultLoadEventListener extends AbstractLockUpgradeEventListener i
} }
else { else {
entity = convertCacheReferenceEntryToEntity( (ReferenceCacheEntryImpl) entry, entity = convertCacheReferenceEntryToEntity( (ReferenceCacheEntryImpl) entry,
event.getEntityId(), persister, event.getSession(), entityKey ); event.getEntityId(), persister, event.getSession(), entityKey, event );
} }
} }
else { else {
@ -638,7 +638,8 @@ public class DefaultLoadEventListener extends AbstractLockUpgradeEventListener i
Serializable entityId, Serializable entityId,
EntityPersister persister, EntityPersister persister,
EventSource session, EventSource session,
EntityKey entityKey) { EntityKey entityKey,
LoadEvent loadEvent) {
final Object entity = referenceCacheEntry.getReference(); final Object entity = referenceCacheEntry.getReference();
if ( entity == null ) { if ( entity == null ) {
@ -651,15 +652,15 @@ public class DefaultLoadEventListener extends AbstractLockUpgradeEventListener i
EventListenerGroup<PostLoadEventListener> evenListenerGroup = getEvenListenerGroup(session); EventListenerGroup<PostLoadEventListener> evenListenerGroup = getEvenListenerGroup(session);
if(!evenListenerGroup.isEmpty()) { if(!evenListenerGroup.isEmpty()) {
postLoad(session, evenListenerGroup.listeners(), entity, entityId, persister); postLoad(session, evenListenerGroup.listeners(), entity, entityId, persister, loadEvent);
} }
return entity; return entity;
} }
} }
private void postLoad(EventSource session, Iterable<PostLoadEventListener> listeners, private void postLoad(EventSource session, Iterable<PostLoadEventListener> listeners,
Object entity, Serializable entityId, EntityPersister persister) { Object entity, Serializable entityId, EntityPersister persister, LoadEvent event) {
PostLoadEvent postLoadEvent = new PostLoadEvent(session) PostLoadEvent postLoadEvent = event.getPostLoadEvent()
.setEntity(entity) .setEntity(entity)
.setId(entityId) .setId(entityId)
.setPersister(persister); .setPersister(persister);
@ -785,7 +786,7 @@ public class DefaultLoadEventListener extends AbstractLockUpgradeEventListener i
persistenceContext.initializeNonLazyCollections(); persistenceContext.initializeNonLazyCollections();
//PostLoad is needed for EJB3 //PostLoad is needed for EJB3
PostLoadEvent postLoadEvent = new PostLoadEvent( session ) PostLoadEvent postLoadEvent = event.getPostLoadEvent()
.setEntity( entity ) .setEntity( entity )
.setId( entityId ) .setId( entityId )
.setPersister( persister ); .setPersister( persister );
@ -880,7 +881,7 @@ public class DefaultLoadEventListener extends AbstractLockUpgradeEventListener i
//PostLoad is needed for EJB3 //PostLoad is needed for EJB3
//TODO: reuse the PostLoadEvent... //TODO: reuse the PostLoadEvent...
PostLoadEvent postLoadEvent = new PostLoadEvent( session ) PostLoadEvent postLoadEvent = event.getPostLoadEvent()
.setEntity( result ) .setEntity( result )
.setId( id ) .setId( id )
.setPersister( persister ); .setPersister( persister );

View File

@ -45,6 +45,7 @@ public class LoadEvent extends AbstractEvent {
private LockOptions lockOptions; private LockOptions lockOptions;
private boolean isAssociationFetch; private boolean isAssociationFetch;
private Object result; private Object result;
private PostLoadEvent postLoadEvent;
public LoadEvent(Serializable entityId, Object instanceToLoad, EventSource source) { public LoadEvent(Serializable entityId, Object instanceToLoad, EventSource source) {
this( entityId, null, instanceToLoad, DEFAULT_LOCK_OPTIONS, false, source ); this( entityId, null, instanceToLoad, DEFAULT_LOCK_OPTIONS, false, source );
@ -104,6 +105,7 @@ public class LoadEvent extends AbstractEvent {
this.instanceToLoad = instanceToLoad; this.instanceToLoad = instanceToLoad;
this.lockOptions = lockOptions; this.lockOptions = lockOptions;
this.isAssociationFetch = isAssociationFetch; this.isAssociationFetch = isAssociationFetch;
this.postLoadEvent = new PostLoadEvent(source);
} }
public Serializable getEntityId() { public Serializable getEntityId() {
@ -180,4 +182,12 @@ public class LoadEvent extends AbstractEvent {
public void setResult(Object result) { public void setResult(Object result) {
this.result = result; this.result = result;
} }
public PostLoadEvent getPostLoadEvent() {
return postLoadEvent;
}
public void setPostLoadEvent(PostLoadEvent postLoadEvent) {
this.postLoadEvent = postLoadEvent;
}
} }

View File

@ -207,6 +207,7 @@ public final class SessionImpl extends AbstractSessionImpl implements EventSourc
private transient ExceptionMapper exceptionMapper; private transient ExceptionMapper exceptionMapper;
private transient ManagedFlushChecker managedFlushChecker; private transient ManagedFlushChecker managedFlushChecker;
private transient AfterCompletionAction afterCompletionAction; private transient AfterCompletionAction afterCompletionAction;
private transient LoadEvent loadEvent; //cached LoadEvent instance
/** /**
* Constructor used for openSession(...) processing, as well as construction * Constructor used for openSession(...) processing, as well as construction
@ -938,8 +939,26 @@ public final class SessionImpl extends AbstractSessionImpl implements EventSourc
@Override @Override
public void load(Object object, Serializable id) throws HibernateException { 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 ); fireLoad( event, LoadEventListener.RELOAD );
if(loadEvent == null) {
event.setEntityClassName(null);
event.setEntityId(null);
event.setInstanceToLoad(null);
event.setResult(null);
loadEvent = event;
}
} }
@Override @Override
@ -973,10 +992,28 @@ public final class SessionImpl extends AbstractSessionImpl implements EventSourc
EntityPersister persister = getFactory().getEntityPersister( entityName ); EntityPersister persister = getFactory().getEntityPersister( entityName );
LOG.debugf( "Initializing proxy: %s", MessageHelper.infoString( persister, id, getFactory() ) ); LOG.debugf( "Initializing proxy: %s", MessageHelper.infoString( persister, id, getFactory() ) );
} }
LoadEvent event = loadEvent;
LoadEvent event = new LoadEvent( id, entityName, true, this ); 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 ); 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 @Override
@ -988,12 +1025,32 @@ public final class SessionImpl extends AbstractSessionImpl implements EventSourc
: eager : eager
? LoadEventListener.INTERNAL_LOAD_EAGER ? LoadEventListener.INTERNAL_LOAD_EAGER
: LoadEventListener.INTERNAL_LOAD_LAZY; : LoadEventListener.INTERNAL_LOAD_LAZY;
LoadEvent event = new LoadEvent( id, entityName, true, this );
fireLoad( event, type ); LoadEvent event = loadEvent;
if ( !nullable ) { loadEvent = null;
UnresolvableObjectException.throwIfNull( event.getResult(), id, entityName ); 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 @Override