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 6777977df0
commit a761705e1d
3 changed files with 84 additions and 16 deletions

View File

@ -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<PostLoadEventListener> 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<PostLoadEventListener> 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 );

View File

@ -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;
}
}

View File

@ -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