HHH-14447 Add missing EventGroupListeners into FastSessionService and take advantage of them

This commit is contained in:
Sanne Grinovero 2021-01-25 21:25:39 +00:00 committed by Andrea Boriero
parent 14e181806f
commit 81a9b87ec1
14 changed files with 264 additions and 233 deletions

View File

@ -20,6 +20,7 @@ import org.hibernate.event.service.spi.EventListenerGroup;
import org.hibernate.event.service.spi.EventListenerRegistry;
import org.hibernate.event.spi.EventSource;
import org.hibernate.event.spi.EventType;
import org.hibernate.internal.FastSessionServices;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.pretty.MessageHelper;
@ -184,6 +185,11 @@ public abstract class CollectionAction implements Executable, Serializable, Comp
}
}
/**
* @deprecated This will be removed as it's not very efficient. If you need access to EventListenerGroup(s),
* use the direct references from {@link #getFastSessionServices()}.
*/
@Deprecated
protected <T> EventListenerGroup<T> listenerGroup(EventType<T> eventType) {
return getSession()
.getFactory()
@ -195,4 +201,13 @@ public abstract class CollectionAction implements Executable, Serializable, Comp
protected EventSource eventSource() {
return (EventSource) getSession();
}
/**
* Convenience method for all subclasses.
* @return the {@link FastSessionServices} instance from the SessionFactory.
*/
protected FastSessionServices getFastSessionServices() {
return session.getFactory().getFastSessionServices();
}
}

View File

@ -11,8 +11,6 @@ import java.io.Serializable;
import org.hibernate.HibernateException;
import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.event.service.spi.EventListenerGroup;
import org.hibernate.event.spi.EventType;
import org.hibernate.event.spi.PostCollectionRecreateEvent;
import org.hibernate.event.spi.PostCollectionRecreateEventListener;
import org.hibernate.event.spi.PreCollectionRecreateEvent;
@ -61,24 +59,22 @@ public final class CollectionRecreateAction extends CollectionAction {
}
private void preRecreate() {
final EventListenerGroup<PreCollectionRecreateEventListener> listenerGroup = listenerGroup( EventType.PRE_COLLECTION_RECREATE );
if ( listenerGroup.isEmpty() ) {
return;
}
final PreCollectionRecreateEvent event = new PreCollectionRecreateEvent( getPersister(), getCollection(), eventSource() );
for ( PreCollectionRecreateEventListener listener : listenerGroup.listeners() ) {
listener.onPreRecreateCollection( event );
}
getFastSessionServices()
.eventListenerGroup_PRE_COLLECTION_RECREATE
.fireLazyEventOnEachListener( this::newPreCollectionRecreateEvent, PreCollectionRecreateEventListener::onPreRecreateCollection );
}
private PreCollectionRecreateEvent newPreCollectionRecreateEvent() {
return new PreCollectionRecreateEvent( getPersister(), getCollection(), eventSource() );
}
private void postRecreate() {
final EventListenerGroup<PostCollectionRecreateEventListener> listenerGroup = listenerGroup( EventType.POST_COLLECTION_RECREATE );
if ( listenerGroup.isEmpty() ) {
return;
}
final PostCollectionRecreateEvent event = new PostCollectionRecreateEvent( getPersister(), getCollection(), eventSource() );
for ( PostCollectionRecreateEventListener listener : listenerGroup.listeners() ) {
listener.onPostRecreateCollection( event );
}
getFastSessionServices()
.eventListenerGroup_POST_COLLECTION_RECREATE
.fireLazyEventOnEachListener( this::newPostCollectionRecreateEvent, PostCollectionRecreateEventListener::onPostRecreateCollection );
}
private PostCollectionRecreateEvent newPostCollectionRecreateEvent() {
return new PostCollectionRecreateEvent( getPersister(), getCollection(), eventSource() );
}
}

View File

@ -114,34 +114,33 @@ public final class CollectionRemoveAction extends CollectionAction {
}
private void preRemove() {
final EventListenerGroup<PreCollectionRemoveEventListener> listenerGroup = listenerGroup( EventType.PRE_COLLECTION_REMOVE );
if ( listenerGroup.isEmpty() ) {
return;
}
final PreCollectionRemoveEvent event = new PreCollectionRemoveEvent(
getFastSessionServices()
.eventListenerGroup_PRE_COLLECTION_REMOVE
.fireLazyEventOnEachListener( this::newPreCollectionRemoveEvent, PreCollectionRemoveEventListener::onPreRemoveCollection );
}
private PreCollectionRemoveEvent newPreCollectionRemoveEvent() {
return new PreCollectionRemoveEvent(
getPersister(),
getCollection(),
eventSource(),
affectedOwner
);
for ( PreCollectionRemoveEventListener listener : listenerGroup.listeners() ) {
listener.onPreRemoveCollection( event );
}
}
private void postRemove() {
final EventListenerGroup<PostCollectionRemoveEventListener> listenerGroup = listenerGroup( EventType.POST_COLLECTION_REMOVE );
if ( listenerGroup.isEmpty() ) {
return;
}
final PostCollectionRemoveEvent event = new PostCollectionRemoveEvent(
getFastSessionServices()
.eventListenerGroup_POST_COLLECTION_REMOVE
.fireLazyEventOnEachListener( this::newPostCollectionRemoveEvent, PostCollectionRemoveEventListener::onPostRemoveCollection );
}
private PostCollectionRemoveEvent newPostCollectionRemoveEvent() {
return new PostCollectionRemoveEvent(
getPersister(),
getCollection(),
eventSource(),
affectedOwner
);
for ( PostCollectionRemoveEventListener listener : listenerGroup.listeners() ) {
listener.onPostRemoveCollection( event );
}
}
}

View File

@ -100,32 +100,31 @@ public final class CollectionUpdateAction extends CollectionAction {
}
private void preUpdate() {
final EventListenerGroup<PreCollectionUpdateEventListener> listenerGroup = listenerGroup( EventType.PRE_COLLECTION_UPDATE );
if ( listenerGroup.isEmpty() ) {
return;
}
final PreCollectionUpdateEvent event = new PreCollectionUpdateEvent(
getFastSessionServices()
.eventListenerGroup_PRE_COLLECTION_UPDATE
.fireLazyEventOnEachListener( this::newPreCollectionUpdateEvent, PreCollectionUpdateEventListener::onPreUpdateCollection );
}
private PreCollectionUpdateEvent newPreCollectionUpdateEvent() {
return new PreCollectionUpdateEvent(
getPersister(),
getCollection(),
eventSource()
);
for ( PreCollectionUpdateEventListener listener : listenerGroup.listeners() ) {
listener.onPreUpdateCollection( event );
}
}
private void postUpdate() {
final EventListenerGroup<PostCollectionUpdateEventListener> listenerGroup = listenerGroup( EventType.POST_COLLECTION_UPDATE );
if ( listenerGroup.isEmpty() ) {
return;
}
final PostCollectionUpdateEvent event = new PostCollectionUpdateEvent(
getFastSessionServices()
.eventListenerGroup_POST_COLLECTION_UPDATE
.fireLazyEventOnEachListener( this::newPostCollectionUpdateEvent, PostCollectionUpdateEventListener::onPostUpdateCollection );
}
private PostCollectionUpdateEvent newPostCollectionUpdateEvent() {
return new PostCollectionUpdateEvent(
getPersister(),
getCollection(),
eventSource()
);
for ( PostCollectionUpdateEventListener listener : listenerGroup.listeners() ) {
listener.onPostUpdateCollection( event );
}
}
}

View File

@ -18,12 +18,11 @@ import org.hibernate.event.service.spi.EventListenerGroup;
import org.hibernate.event.service.spi.EventListenerRegistry;
import org.hibernate.event.spi.EventSource;
import org.hibernate.event.spi.EventType;
import org.hibernate.internal.FastSessionServices;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.pretty.MessageHelper;
import org.jboss.logging.Logger;
/**
* Base class for actions relating to insert/update/delete of an entity
* instance.
@ -32,7 +31,6 @@ import org.jboss.logging.Logger;
*/
public abstract class EntityAction
implements Executable, Serializable, Comparable, AfterTransactionCompletionProcess {
private static final Logger LOG = Logger.getLogger(EntityAction.class);
private final String entityName;
private final Serializable id;
@ -189,6 +187,11 @@ public abstract class EntityAction
}
}
/**
* @deprecated This will be removed as it's not very efficient. If you need access to EventListenerGroup(s),
* use the direct references from {@link #getFastSessionServices()}.
*/
@Deprecated
protected <T> EventListenerGroup<T> listenerGroup(EventType<T> eventType) {
return getSession()
.getFactory()
@ -200,4 +203,13 @@ public abstract class EntityAction
protected EventSource eventSource() {
return (EventSource) getSession();
}
/**
* Convenience method for all subclasses.
* @return the {@link FastSessionServices} instance from the SessionFactory.
*/
protected FastSessionServices getFastSessionServices() {
return session.getFactory().getFastSessionServices();
}
}

View File

@ -17,7 +17,6 @@ import org.hibernate.engine.spi.PersistenceContext;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.event.service.spi.EventListenerGroup;
import org.hibernate.event.spi.EventType;
import org.hibernate.event.spi.PostCommitDeleteEventListener;
import org.hibernate.event.spi.PostDeleteEvent;
import org.hibernate.event.spi.PostDeleteEventListener;
@ -154,7 +153,7 @@ public class EntityDeleteAction extends EntityAction {
protected boolean preDelete() {
boolean veto = false;
final EventListenerGroup<PreDeleteEventListener> listenerGroup = listenerGroup( EventType.PRE_DELETE );
final EventListenerGroup<PreDeleteEventListener> listenerGroup = getFastSessionServices().eventListenerGroup_PRE_DELETE;
if ( listenerGroup.isEmpty() ) {
return veto;
}
@ -166,47 +165,49 @@ public class EntityDeleteAction extends EntityAction {
}
protected void postDelete() {
final EventListenerGroup<PostDeleteEventListener> listenerGroup = listenerGroup( EventType.POST_DELETE );
if ( listenerGroup.isEmpty() ) {
return;
}
final PostDeleteEvent event = new PostDeleteEvent(
getFastSessionServices()
.eventListenerGroup_POST_DELETE
.fireLazyEventOnEachListener( this::newPostDeleteEvent, PostDeleteEventListener::onPostDelete );
}
PostDeleteEvent newPostDeleteEvent() {
return new PostDeleteEvent(
getInstance(),
getId(),
state,
getPersister(),
eventSource()
);
for ( PostDeleteEventListener listener : listenerGroup.listeners() ) {
}
protected void postCommitDelete(boolean success) {
final EventListenerGroup<PostDeleteEventListener> eventListeners = getFastSessionServices()
.eventListenerGroup_POST_COMMIT_DELETE;
if (success) {
eventListeners.fireLazyEventOnEachListener( this::newPostDeleteEvent, EntityDeleteAction::postCommitDeleteOnSuccess );
}
else {
eventListeners.fireLazyEventOnEachListener( this::newPostDeleteEvent, EntityDeleteAction::postCommitDeleteOnUnsuccessful );
}
}
private static void postCommitDeleteOnSuccess(PostDeleteEventListener listener, PostDeleteEvent event) {
if ( listener instanceof PostCommitDeleteEventListener ) {
listener.onPostDelete( event );
}
else {
//default to the legacy implementation that always fires the event
listener.onPostDelete( event );
}
}
protected void postCommitDelete(boolean success) {
final EventListenerGroup<PostDeleteEventListener> listenerGroup = listenerGroup( EventType.POST_COMMIT_DELETE );
if ( listenerGroup.isEmpty() ) {
return;
private static void postCommitDeleteOnUnsuccessful(PostDeleteEventListener listener, PostDeleteEvent event) {
if ( listener instanceof PostCommitDeleteEventListener ) {
( (PostCommitDeleteEventListener) listener ).onPostDeleteCommitFailed( event );
}
final PostDeleteEvent event = new PostDeleteEvent(
getInstance(),
getId(),
state,
getPersister(),
eventSource()
);
for ( PostDeleteEventListener listener : listenerGroup.listeners() ) {
if ( PostCommitDeleteEventListener.class.isInstance( listener ) ) {
if ( success ) {
listener.onPostDelete( event );
}
else {
((PostCommitDeleteEventListener) listener).onPostDeleteCommitFailed( event );
}
}
else {
//default to the legacy implementation that always fires the event
listener.onPostDelete( event );
}
else {
//default to the legacy implementation that always fires the event
listener.onPostDelete( event );
}
}
@ -228,7 +229,7 @@ public class EntityDeleteAction extends EntityAction {
@Override
protected boolean hasPostCommitEventListeners() {
final EventListenerGroup<PostDeleteEventListener> group = listenerGroup( EventType.POST_COMMIT_DELETE );
final EventListenerGroup<PostDeleteEventListener> group = getFastSessionServices().eventListenerGroup_POST_COMMIT_DELETE;
for ( PostDeleteEventListener listener : group.listeners() ) {
if ( listener.requiresPostCommitHandling( getPersister() ) ) {
return true;

View File

@ -121,7 +121,7 @@ public class EntityIdentityInsertAction extends AbstractEntityInsertAction {
@Override
protected boolean hasPostCommitEventListeners() {
final EventListenerGroup<PostInsertEventListener> group = listenerGroup( EventType.POST_COMMIT_INSERT );
final EventListenerGroup<PostInsertEventListener> group = getFastSessionServices().eventListenerGroup_POST_COMMIT_INSERT;
for ( PostInsertEventListener listener : group.listeners() ) {
if ( listener.requiresPostCommitHandling( getPersister() ) ) {
return true;
@ -142,57 +142,42 @@ public class EntityIdentityInsertAction extends AbstractEntityInsertAction {
}
protected void postInsert() {
final EventSource eventSource = eventSource();
if ( isDelayed ) {
eventSource.getPersistenceContextInternal().replaceDelayedEntityIdentityInsertKeys( delayedEntityKey, generatedId );
}
final EventListenerGroup<PostInsertEventListener> listenerGroup = listenerGroup( EventType.POST_INSERT );
if ( listenerGroup.isEmpty() ) {
return;
}
final PostInsertEvent event = new PostInsertEvent(
getInstance(),
generatedId,
getState(),
getPersister(),
eventSource
);
for ( PostInsertEventListener listener : listenerGroup.listeners() ) {
listener.onPostInsert( event );
eventSource().getPersistenceContextInternal().replaceDelayedEntityIdentityInsertKeys( delayedEntityKey, generatedId );
}
getFastSessionServices()
.eventListenerGroup_POST_INSERT
.fireLazyEventOnEachListener( this::newPostInsertEvent, PostInsertEventListener::onPostInsert );
}
protected void postCommitInsert(boolean success) {
final EventListenerGroup<PostInsertEventListener> listenerGroup = listenerGroup( EventType.POST_COMMIT_INSERT );
if ( listenerGroup.isEmpty() ) {
return;
}
final PostInsertEvent event = new PostInsertEvent(
PostInsertEvent newPostInsertEvent() {
return new PostInsertEvent(
getInstance(),
generatedId,
getState(),
getPersister(),
eventSource()
);
for ( PostInsertEventListener listener : listenerGroup.listeners() ) {
if ( PostCommitInsertEventListener.class.isInstance( listener ) ) {
if ( success ) {
listener.onPostInsert( event );
}
else {
((PostCommitInsertEventListener) listener).onPostInsertCommitFailed( event );
}
}
else {
//default to the legacy implementation that always fires the event
listener.onPostInsert( event );
}
}
protected void postCommitInsert(boolean success) {
getFastSessionServices()
.eventListenerGroup_POST_COMMIT_INSERT
.fireLazyEventOnEachListener( this::newPostInsertEvent, success ? PostInsertEventListener::onPostInsert : this::postCommitInsertOnFailure );
}
private void postCommitInsertOnFailure(PostInsertEventListener listener, PostInsertEvent event) {
if ( listener instanceof PostCommitInsertEventListener ) {
((PostCommitInsertEventListener) listener).onPostInsertCommitFailed( event );
}
else {
//default to the legacy implementation that always fires the event
listener.onPostInsert( event );
}
}
protected boolean preInsert() {
final EventListenerGroup<PreInsertEventListener> listenerGroup = listenerGroup( EventType.PRE_INSERT );
final EventListenerGroup<PreInsertEventListener> listenerGroup = getFastSessionServices().eventListenerGroup_PRE_INSERT;
if ( listenerGroup.isEmpty() ) {
// NO_VETO
return false;

View File

@ -171,54 +171,41 @@ public class EntityInsertAction extends AbstractEntityInsertAction {
}
protected void postInsert() {
final EventListenerGroup<PostInsertEventListener> listenerGroup = listenerGroup( EventType.POST_INSERT );
if ( listenerGroup.isEmpty() ) {
return;
}
final PostInsertEvent event = new PostInsertEvent(
getFastSessionServices()
.eventListenerGroup_POST_INSERT
.fireLazyEventOnEachListener( this::newPostInsertEvent, PostInsertEventListener::onPostInsert );
}
private PostInsertEvent newPostInsertEvent() {
return new PostInsertEvent(
getInstance(),
getId(),
getState(),
getPersister(),
eventSource()
);
for ( PostInsertEventListener listener : listenerGroup.listeners() ) {
listener.onPostInsert( event );
}
}
protected void postCommitInsert(boolean success) {
final EventListenerGroup<PostInsertEventListener> listenerGroup = listenerGroup( EventType.POST_COMMIT_INSERT );
if ( listenerGroup.isEmpty() ) {
return;
getFastSessionServices()
.eventListenerGroup_POST_COMMIT_INSERT
.fireLazyEventOnEachListener( this::newPostInsertEvent, success ? PostInsertEventListener::onPostInsert : this::postCommitOnFailure );
}
private void postCommitOnFailure(PostInsertEventListener listener, PostInsertEvent event) {
if ( listener instanceof PostCommitInsertEventListener ) {
((PostCommitInsertEventListener) listener).onPostInsertCommitFailed( event );
}
final PostInsertEvent event = new PostInsertEvent(
getInstance(),
getId(),
getState(),
getPersister(),
eventSource()
);
for ( PostInsertEventListener listener : listenerGroup.listeners() ) {
if ( PostCommitInsertEventListener.class.isInstance( listener ) ) {
if ( success ) {
listener.onPostInsert( event );
}
else {
((PostCommitInsertEventListener) listener).onPostInsertCommitFailed( event );
}
}
else {
//default to the legacy implementation that always fires the event
listener.onPostInsert( event );
}
else {
//default to the legacy implementation that always fires the event
listener.onPostInsert( event );
}
}
protected boolean preInsert() {
boolean veto = false;
final EventListenerGroup<PreInsertEventListener> listenerGroup = listenerGroup( EventType.PRE_INSERT );
final EventListenerGroup<PreInsertEventListener> listenerGroup = getFastSessionServices().eventListenerGroup_PRE_INSERT;
if ( listenerGroup.isEmpty() ) {
return veto;
}
@ -263,13 +250,12 @@ public class EntityInsertAction extends AbstractEntityInsertAction {
@Override
protected boolean hasPostCommitEventListeners() {
final EventListenerGroup<PostInsertEventListener> group = listenerGroup( EventType.POST_COMMIT_INSERT );
final EventListenerGroup<PostInsertEventListener> group = getFastSessionServices().eventListenerGroup_POST_COMMIT_INSERT;
for ( PostInsertEventListener listener : group.listeners() ) {
if ( listener.requiresPostCommitHandling( getPersister() ) ) {
return true;
}
}
return false;
}

View File

@ -288,7 +288,7 @@ public class EntityUpdateAction extends EntityAction {
protected boolean preUpdate() {
boolean veto = false;
final EventListenerGroup<PreUpdateEventListener> listenerGroup = listenerGroup( EventType.PRE_UPDATE );
final EventListenerGroup<PreUpdateEventListener> listenerGroup = getFastSessionServices().eventListenerGroup_PRE_UPDATE;
if ( listenerGroup.isEmpty() ) {
return veto;
}
@ -307,11 +307,13 @@ public class EntityUpdateAction extends EntityAction {
}
protected void postUpdate() {
final EventListenerGroup<PostUpdateEventListener> listenerGroup = listenerGroup( EventType.POST_UPDATE );
if ( listenerGroup.isEmpty() ) {
return;
}
final PostUpdateEvent event = new PostUpdateEvent(
getFastSessionServices()
.eventListenerGroup_POST_UPDATE
.fireLazyEventOnEachListener( this::newPostUpdateEvent, PostUpdateEventListener::onPostUpdate );
}
private PostUpdateEvent newPostUpdateEvent() {
return new PostUpdateEvent(
getInstance(),
getId(),
state,
@ -320,44 +322,27 @@ public class EntityUpdateAction extends EntityAction {
getPersister(),
eventSource()
);
for ( PostUpdateEventListener listener : listenerGroup.listeners() ) {
listener.onPostUpdate( event );
}
}
protected void postCommitUpdate(boolean success) {
final EventListenerGroup<PostUpdateEventListener> listenerGroup = listenerGroup( EventType.POST_COMMIT_UPDATE );
if ( listenerGroup.isEmpty() ) {
return;
getFastSessionServices()
.eventListenerGroup_POST_COMMIT_UPDATE
.fireLazyEventOnEachListener( this::newPostUpdateEvent, success ? PostUpdateEventListener::onPostUpdate : this::onPostCommitFailure );
}
private void onPostCommitFailure(PostUpdateEventListener listener, PostUpdateEvent event) {
if ( listener instanceof PostCommitUpdateEventListener ) {
((PostCommitUpdateEventListener) listener).onPostUpdateCommitFailed( event );
}
final PostUpdateEvent event = new PostUpdateEvent(
getInstance(),
getId(),
state,
previousState,
dirtyFields,
getPersister(),
eventSource()
);
for ( PostUpdateEventListener listener : listenerGroup.listeners() ) {
if ( PostCommitUpdateEventListener.class.isInstance( listener ) ) {
if ( success ) {
listener.onPostUpdate( event );
}
else {
((PostCommitUpdateEventListener) listener).onPostUpdateCommitFailed( event );
}
}
else {
//default to the legacy implementation that always fires the event
listener.onPostUpdate( event );
}
else {
//default to the legacy implementation that always fires the event
listener.onPostUpdate( event );
}
}
@Override
protected boolean hasPostCommitEventListeners() {
final EventListenerGroup<PostUpdateEventListener> group = listenerGroup( EventType.POST_COMMIT_UPDATE );
final EventListenerGroup<PostUpdateEventListener> group = getFastSessionServices().eventListenerGroup_POST_COMMIT_UPDATE;
for ( PostUpdateEventListener listener : group.listeners() ) {
if ( listener.requiresPostCommitHandling( getPersister() ) ) {
return true;

View File

@ -28,6 +28,7 @@ import org.hibernate.engine.spi.EntityEntry;
import org.hibernate.engine.spi.PersistenceContext;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.engine.spi.Status;
import org.hibernate.event.service.spi.EventListenerGroup;
import org.hibernate.event.service.spi.EventListenerRegistry;
import org.hibernate.event.service.spi.JpaBootstrapSensitive;
import org.hibernate.event.spi.EventSource;
@ -205,10 +206,8 @@ public abstract class AbstractFlushingEventListener implements JpaBootstrapSensi
LOG.trace( "Flushing entities and processing referenced collections" );
final EventSource source = event.getSession();
final Iterable<FlushEntityEventListener> flushListeners = source.getFactory().getServiceRegistry()
.getService( EventListenerRegistry.class )
.getEventListenerGroup( EventType.FLUSH_ENTITY )
.listeners();
final EventListenerGroup<FlushEntityEventListener> flushListeners = source.getFactory()
.getFastSessionServices().eventListenerGroup_FLUSH_ENTITY;
// Among other things, updateReachables() will recursively load all
// collections that are moving roles. This might cause entities to
@ -228,9 +227,7 @@ public abstract class AbstractFlushingEventListener implements JpaBootstrapSensi
if ( status != Status.LOADING && status != Status.GONE ) {
final FlushEntityEvent entityEvent = new FlushEntityEvent( source, me.getKey(), entry );
for ( FlushEntityEventListener listener : flushListeners ) {
listener.onFlushEntity( entityEvent );
}
flushListeners.fireEventOnEachListener( entityEvent, FlushEntityEventListener::onFlushEntity );
}
}

View File

@ -80,7 +80,7 @@ public interface EventListenerGroup<T> extends Serializable {
* Fires an event on each registered event listener of this group.
*
* Implementation note (performance):
* the first argument is a supplier so that events can avoid allocation when no listener is registered.
* the first argument is a supplier so that events can avoid being created when no listener is registered.
* the second argument is specifically designed to avoid needing a capturing lambda.
*
* @param eventSupplier
@ -88,7 +88,7 @@ public interface EventListenerGroup<T> extends Serializable {
* @param <U> the kind of event
*/
@Incubating
<U> void fireLazyEventOnEachListener(final Supplier<U> eventSupplier, final BiConsumer<T,U> actionOnEvent);
<U> void fireLazyEventOnEachListener(final Supplier<U> eventSupplier, final BiConsumer<T,U> actionOnEvent);
/**
* Similar as {@link #fireLazyEventOnEachListener(Supplier, BiConsumer)} except it doesn't use a {{@link Supplier}}:
@ -98,9 +98,19 @@ public interface EventListenerGroup<T> extends Serializable {
* @param <U> the kind of event
*/
@Incubating
<U> void fireEventOnEachListener(final U event, final BiConsumer<T,U> actionOnEvent);
<U> void fireEventOnEachListener(final U event, final BiConsumer<T,U> actionOnEvent);
/**
* Similar to {@link #fireEventOnEachListener(Object, BiConsumer)}, but allows passing a third parameter
* to the consumer; our code based occasionally needs a third parameter: having this additional variant
* allows using the optimal iteration more extensively and reduce allocations.
* @param event
* @param param
* @param actionOnEvent
* @param <U>
* @param <X>
*/
@Incubating
<U,X> void fireEventOnEachListener(final U event, X param, final EventActionWithParameter<T,U,X> actionOnEvent);
<U,X> void fireEventOnEachListener(final U event, X param, final EventActionWithParameter<T,U,X> actionOnEvent);
}

View File

@ -26,14 +26,28 @@ import org.hibernate.event.spi.DeleteEventListener;
import org.hibernate.event.spi.DirtyCheckEventListener;
import org.hibernate.event.spi.EventType;
import org.hibernate.event.spi.EvictEventListener;
import org.hibernate.event.spi.FlushEntityEventListener;
import org.hibernate.event.spi.FlushEventListener;
import org.hibernate.event.spi.InitializeCollectionEventListener;
import org.hibernate.event.spi.LoadEventListener;
import org.hibernate.event.spi.LockEventListener;
import org.hibernate.event.spi.MergeEventListener;
import org.hibernate.event.spi.PersistEventListener;
import org.hibernate.event.spi.PostCollectionRecreateEventListener;
import org.hibernate.event.spi.PostCollectionRemoveEventListener;
import org.hibernate.event.spi.PostCollectionUpdateEventListener;
import org.hibernate.event.spi.PostDeleteEventListener;
import org.hibernate.event.spi.PostInsertEventListener;
import org.hibernate.event.spi.PostLoadEvent;
import org.hibernate.event.spi.PostLoadEventListener;
import org.hibernate.event.spi.PostUpdateEventListener;
import org.hibernate.event.spi.PreCollectionRecreateEventListener;
import org.hibernate.event.spi.PreCollectionRemoveEventListener;
import org.hibernate.event.spi.PreCollectionUpdateEventListener;
import org.hibernate.event.spi.PreDeleteEventListener;
import org.hibernate.event.spi.PreInsertEventListener;
import org.hibernate.event.spi.PreLoadEventListener;
import org.hibernate.event.spi.PreUpdateEventListener;
import org.hibernate.event.spi.RefreshEventListener;
import org.hibernate.event.spi.ReplicateEventListener;
import org.hibernate.event.spi.ResolveNaturalIdEventListener;
@ -89,28 +103,44 @@ public final class FastSessionServices {
*/
final Map<String, Object> defaultSessionProperties;
// All session events need to be iterated frequently:
final EventListenerGroup<AutoFlushEventListener> eventListenerGroup_AUTO_FLUSH;
final EventListenerGroup<ClearEventListener> eventListenerGroup_CLEAR;
final EventListenerGroup<DeleteEventListener> eventListenerGroup_DELETE;
final EventListenerGroup<DirtyCheckEventListener> eventListenerGroup_DIRTY_CHECK;
final EventListenerGroup<EvictEventListener> eventListenerGroup_EVICT;
final EventListenerGroup<FlushEventListener> eventListenerGroup_FLUSH;
final EventListenerGroup<InitializeCollectionEventListener> eventListenerGroup_INIT_COLLECTION;
final EventListenerGroup<LoadEventListener> eventListenerGroup_LOAD;
final EventListenerGroup<LockEventListener> eventListenerGroup_LOCK;
final EventListenerGroup<MergeEventListener> eventListenerGroup_MERGE;
final EventListenerGroup<PersistEventListener> eventListenerGroup_PERSIST;
final EventListenerGroup<PersistEventListener> eventListenerGroup_PERSIST_ONFLUSH;
final EventListenerGroup<RefreshEventListener> eventListenerGroup_REFRESH;
final EventListenerGroup<ReplicateEventListener> eventListenerGroup_REPLICATE;
final EventListenerGroup<ResolveNaturalIdEventListener> eventListenerGroup_RESOLVE_NATURAL_ID;
final EventListenerGroup<SaveOrUpdateEventListener> eventListenerGroup_SAVE;
final EventListenerGroup<SaveOrUpdateEventListener> eventListenerGroup_SAVE_UPDATE;
final EventListenerGroup<SaveOrUpdateEventListener> eventListenerGroup_UPDATE;
//Frequently used by 2LC initialization:
final EventListenerGroup<PostLoadEventListener> eventListenerGroup_POST_LOAD;
// All session events need to be iterated frequently; CollectionAction and EventAction also need
// most of these very frequently:
public final EventListenerGroup<AutoFlushEventListener> eventListenerGroup_AUTO_FLUSH;
public final EventListenerGroup<ClearEventListener> eventListenerGroup_CLEAR;
public final EventListenerGroup<DeleteEventListener> eventListenerGroup_DELETE;
public final EventListenerGroup<DirtyCheckEventListener> eventListenerGroup_DIRTY_CHECK;
public final EventListenerGroup<EvictEventListener> eventListenerGroup_EVICT;
public final EventListenerGroup<FlushEntityEventListener> eventListenerGroup_FLUSH_ENTITY;
public final EventListenerGroup<FlushEventListener> eventListenerGroup_FLUSH;
public final EventListenerGroup<InitializeCollectionEventListener> eventListenerGroup_INIT_COLLECTION;
public final EventListenerGroup<LoadEventListener> eventListenerGroup_LOAD;
public final EventListenerGroup<LockEventListener> eventListenerGroup_LOCK;
public final EventListenerGroup<MergeEventListener> eventListenerGroup_MERGE;
public final EventListenerGroup<PersistEventListener> eventListenerGroup_PERSIST;
public final EventListenerGroup<PersistEventListener> eventListenerGroup_PERSIST_ONFLUSH;
public final EventListenerGroup<PostCollectionRecreateEventListener> eventListenerGroup_POST_COLLECTION_RECREATE;
public final EventListenerGroup<PostCollectionRemoveEventListener> eventListenerGroup_POST_COLLECTION_REMOVE;
public final EventListenerGroup<PostCollectionUpdateEventListener> eventListenerGroup_POST_COLLECTION_UPDATE;
public final EventListenerGroup<PostDeleteEventListener> eventListenerGroup_POST_COMMIT_DELETE;
public final EventListenerGroup<PostDeleteEventListener> eventListenerGroup_POST_DELETE;
public final EventListenerGroup<PostInsertEventListener> eventListenerGroup_POST_COMMIT_INSERT;
public final EventListenerGroup<PostInsertEventListener> eventListenerGroup_POST_INSERT;
public final EventListenerGroup<PostLoadEventListener> eventListenerGroup_POST_LOAD; //Frequently used by 2LC initialization:
public final EventListenerGroup<PostUpdateEventListener> eventListenerGroup_POST_COMMIT_UPDATE;
public final EventListenerGroup<PostUpdateEventListener> eventListenerGroup_POST_UPDATE;
public final EventListenerGroup<PreCollectionRecreateEventListener> eventListenerGroup_PRE_COLLECTION_RECREATE;
public final EventListenerGroup<PreCollectionRemoveEventListener> eventListenerGroup_PRE_COLLECTION_REMOVE;
public final EventListenerGroup<PreCollectionUpdateEventListener> eventListenerGroup_PRE_COLLECTION_UPDATE;
public final EventListenerGroup<PreDeleteEventListener> eventListenerGroup_PRE_DELETE;
public final EventListenerGroup<PreInsertEventListener> eventListenerGroup_PRE_INSERT;
public final EventListenerGroup<PreLoadEventListener> eventListenerGroup_PRE_LOAD;
public final EventListenerGroup<PreUpdateEventListener> eventListenerGroup_PRE_UPDATE;
public final EventListenerGroup<RefreshEventListener> eventListenerGroup_REFRESH;
public final EventListenerGroup<ReplicateEventListener> eventListenerGroup_REPLICATE;
public final EventListenerGroup<ResolveNaturalIdEventListener> eventListenerGroup_RESOLVE_NATURAL_ID;
public final EventListenerGroup<SaveOrUpdateEventListener> eventListenerGroup_SAVE;
public final EventListenerGroup<SaveOrUpdateEventListener> eventListenerGroup_SAVE_UPDATE;
public final EventListenerGroup<SaveOrUpdateEventListener> eventListenerGroup_UPDATE;
//Intentionally Package private:
final boolean disallowOutOfTransactionUpdateOperations;
@ -148,19 +178,36 @@ public final class FastSessionServices {
this.eventListenerGroup_DIRTY_CHECK = listeners( eventListenerRegistry, EventType.DIRTY_CHECK );
this.eventListenerGroup_EVICT = listeners( eventListenerRegistry, EventType.EVICT );
this.eventListenerGroup_FLUSH = listeners( eventListenerRegistry, EventType.FLUSH );
this.eventListenerGroup_FLUSH_ENTITY = listeners( eventListenerRegistry, EventType.FLUSH_ENTITY );
this.eventListenerGroup_INIT_COLLECTION = listeners( eventListenerRegistry, EventType.INIT_COLLECTION );
this.eventListenerGroup_LOAD = listeners( eventListenerRegistry, EventType.LOAD );
this.eventListenerGroup_LOCK = listeners( eventListenerRegistry, EventType.LOCK );
this.eventListenerGroup_MERGE = listeners( eventListenerRegistry, EventType.MERGE );
this.eventListenerGroup_PERSIST = listeners( eventListenerRegistry, EventType.PERSIST );
this.eventListenerGroup_PERSIST_ONFLUSH = listeners( eventListenerRegistry, EventType.PERSIST_ONFLUSH );
this.eventListenerGroup_POST_COLLECTION_RECREATE = listeners( eventListenerRegistry, EventType.POST_COLLECTION_RECREATE );
this.eventListenerGroup_POST_COLLECTION_REMOVE = listeners( eventListenerRegistry, EventType.POST_COLLECTION_REMOVE );
this.eventListenerGroup_POST_COLLECTION_UPDATE = listeners( eventListenerRegistry, EventType.POST_COLLECTION_UPDATE );
this.eventListenerGroup_POST_COMMIT_DELETE = listeners( eventListenerRegistry, EventType.POST_COMMIT_DELETE );
this.eventListenerGroup_POST_COMMIT_INSERT = listeners( eventListenerRegistry, EventType.POST_COMMIT_INSERT );
this.eventListenerGroup_POST_COMMIT_UPDATE = listeners( eventListenerRegistry, EventType.POST_COMMIT_UPDATE );
this.eventListenerGroup_POST_DELETE = listeners( eventListenerRegistry, EventType.POST_DELETE );
this.eventListenerGroup_POST_INSERT = listeners( eventListenerRegistry, EventType.POST_INSERT );
this.eventListenerGroup_POST_LOAD = listeners( eventListenerRegistry, EventType.POST_LOAD );
this.eventListenerGroup_POST_UPDATE = listeners( eventListenerRegistry, EventType.POST_UPDATE );
this.eventListenerGroup_PRE_COLLECTION_RECREATE = listeners( eventListenerRegistry, EventType.PRE_COLLECTION_RECREATE );
this.eventListenerGroup_PRE_COLLECTION_REMOVE = listeners( eventListenerRegistry, EventType.PRE_COLLECTION_REMOVE );
this.eventListenerGroup_PRE_COLLECTION_UPDATE = listeners( eventListenerRegistry, EventType.PRE_COLLECTION_UPDATE );
this.eventListenerGroup_PRE_DELETE = listeners( eventListenerRegistry, EventType.PRE_DELETE );
this.eventListenerGroup_PRE_INSERT = listeners( eventListenerRegistry, EventType.PRE_INSERT );
this.eventListenerGroup_PRE_LOAD = listeners( eventListenerRegistry, EventType.PRE_LOAD );
this.eventListenerGroup_PRE_UPDATE = listeners( eventListenerRegistry, EventType.PRE_UPDATE );
this.eventListenerGroup_REFRESH = listeners( eventListenerRegistry, EventType.REFRESH );
this.eventListenerGroup_REPLICATE = listeners( eventListenerRegistry, EventType.REPLICATE );
this.eventListenerGroup_RESOLVE_NATURAL_ID = listeners( eventListenerRegistry, EventType.RESOLVE_NATURAL_ID );
this.eventListenerGroup_SAVE = listeners( eventListenerRegistry, EventType.SAVE );
this.eventListenerGroup_SAVE_UPDATE = listeners( eventListenerRegistry, EventType.SAVE_UPDATE );
this.eventListenerGroup_UPDATE = listeners( eventListenerRegistry, EventType.UPDATE );
this.eventListenerGroup_POST_LOAD = listeners( eventListenerRegistry, EventType.POST_LOAD );
//Other highly useful constants:
this.dialect = jdbcServices.getJdbcEnvironment().getDialect();
@ -186,6 +233,7 @@ public final class FastSessionServices {
this.defaultSessionEventListeners = sessionFactoryOptions.getBaselineSessionEventsListenerBuilder();
this.defaultLockOptions = initializeDefaultLockOptions( defaultSessionProperties );
this.initialSessionFlushMode = initializeDefaultFlushMode( defaultSessionProperties );
}
private static FlushMode initializeDefaultFlushMode(Map<String, Object> defaultSessionProperties) {

View File

@ -1191,9 +1191,8 @@ public abstract class Loader {
if ( hydratedObjectsSize != 0 ) {
final Iterable<PreLoadEventListener> listeners = session
.getFactory()
.getServiceRegistry()
.getService( EventListenerRegistry.class )
.getEventListenerGroup( EventType.PRE_LOAD )
.getFastSessionServices()
.eventListenerGroup_PRE_LOAD
.listeners();
for ( Object hydratedObject : hydratedObjects ) {

View File

@ -239,9 +239,8 @@ public abstract class AbstractRowReader implements RowReader {
final SharedSessionContractImplementor session = context.getSession();
final Iterable<PreLoadEventListener> listeners = session
.getFactory()
.getServiceRegistry()
.getService( EventListenerRegistry.class )
.getEventListenerGroup( EventType.PRE_LOAD )
.getFastSessionServices()
.eventListenerGroup_PRE_LOAD
.listeners();
for ( HydratedEntityRegistration registration : hydratedEntityRegistrations ) {