HHH-13565 Convert iteration of event listeners to be allocation free

This commit is contained in:
Sanne Grinovero 2019-08-19 22:31:24 +01:00
parent 269d5f8358
commit b8f3fc3616
4 changed files with 132 additions and 205 deletions

View File

@ -9,9 +9,10 @@ package org.hibernate.event.service.internal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.ListIterator;
import java.util.Set;
import java.util.function.BiConsumer;
import java.util.function.Supplier;
import org.hibernate.event.service.spi.DuplicationStrategy;
import org.hibernate.event.service.spi.EventListenerGroup;
@ -28,7 +29,10 @@ class EventListenerGroupImpl<T> implements EventListenerGroup<T> {
private final EventListenerRegistryImpl listenerRegistry;
private final Set<DuplicationStrategy> duplicationStrategies = new LinkedHashSet<>();
private List<T> listeners;
// Performance: make sure a forEach iteration on this type is efficient; in particular we choose ArrayList
// so to avoid allocating iterators.
private ArrayList<T> listeners;
public EventListenerGroupImpl(EventType<T> eventType, EventListenerRegistryImpl listenerRegistry) {
this.eventType = eventType;
@ -75,6 +79,25 @@ class EventListenerGroupImpl<T> implements EventListenerGroup<T> {
}
}
@Override
public final <U> void fireLazyEventOnEachListener(final Supplier<U> eventSupplier, final BiConsumer<T,U> actionOnEvent) {
if ( listeners != null && listeners.size() != 0 ) {
final U event = eventSupplier.get();
for ( T listener : this.listeners ) {
actionOnEvent.accept( listener, event );
}
}
}
@Override
public final <U> void fireEventOnEachListener(final U event, final BiConsumer<T,U> actionOnEvent) {
if ( listeners != null ) {
for ( T listener : this.listeners ) {
actionOnEvent.accept( listener, event );
}
}
}
@Override
public void addDuplicationStrategy(DuplicationStrategy strategy) {
duplicationStrategies.add( strategy );

View File

@ -7,6 +7,8 @@
package org.hibernate.event.service.spi;
import java.io.Serializable;
import java.util.function.BiConsumer;
import java.util.function.Supplier;
import org.hibernate.event.spi.EventType;
@ -54,4 +56,26 @@ public interface EventListenerGroup<T> extends Serializable {
public void clear();
/**
* 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 second argument is specifically designed to avoid needing a capturing lambda.
*
* @param eventSupplier
* @param actionOnEvent
* @param <U> the kind of event
*/
<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}}:
* useful when there is no need to lazily initialize the event.
* @param event
* @param actionOnEvent
* @param <U> the kind of event
*/
<U> void fireEventOnEachListener(final U event, final BiConsumer<T,U> actionOnEvent);
}

View File

@ -18,6 +18,7 @@ import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;
import org.hibernate.engine.jdbc.connections.spi.MultiTenantConnectionProvider;
import org.hibernate.engine.jdbc.spi.ConnectionObserver;
import org.hibernate.engine.jdbc.spi.JdbcServices;
import org.hibernate.event.service.spi.EventListenerGroup;
import org.hibernate.event.service.spi.EventListenerRegistry;
import org.hibernate.event.spi.AutoFlushEventListener;
import org.hibernate.event.spi.ClearEventListener;
@ -85,25 +86,24 @@ final class FastSessionServices {
final Map<String, Object> defaultSessionProperties;
// All session events need to be iterated frequently:
private final Iterable<ClearEventListener> clearEventListeners;
private final Iterable<SaveOrUpdateEventListener> saveUpdateEventListeners;
private final Iterable<EvictEventListener> evictEventListeners;
private final Iterable<SaveOrUpdateEventListener> saveEventListeners;
private final Iterable<SaveOrUpdateEventListener> updateEventListeners;
private final Iterable<LockEventListener> lockEventListeners;
private final Iterable<PersistEventListener> persistEventListeners;
private final Iterable<PersistEventListener> persistOnFlushEventListeners;
private final Iterable<MergeEventListener> mergeEventListeners;
private final Iterable<DeleteEventListener> deleteEventListeners;
private final Iterable<LoadEventListener> loadEventListeners;
private final Iterable<RefreshEventListener> refreshEventListeners;
private final Iterable<ReplicateEventListener> replicateEventListeners;
private final Iterable<AutoFlushEventListener> autoFlushEventListeners;
private final Iterable<DirtyCheckEventListener> dirtyCheckEventListeners;
private final Iterable<FlushEventListener> flushEventListeners;
private final Iterable<InitializeCollectionEventListener> initCollectionEventListeners;
private final Iterable<ResolveNaturalIdEventListener> resolveNaturalIdEventListeners;
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;
//Intentionally Package private:
final boolean disallowOutOfTransactionUpdateOperations;
@ -133,24 +133,24 @@ final class FastSessionServices {
// Pre-compute all iterators on Event listeners:
final EventListenerRegistry eventListenerRegistry = sr.getService( EventListenerRegistry.class );
this.clearEventListeners = listeners( eventListenerRegistry, EventType.CLEAR );
this.saveUpdateEventListeners = listeners( eventListenerRegistry, EventType.SAVE_UPDATE );
this.evictEventListeners = listeners( eventListenerRegistry, EventType.EVICT );
this.saveEventListeners = listeners( eventListenerRegistry, EventType.SAVE );
this.updateEventListeners = listeners( eventListenerRegistry, EventType.UPDATE );
this.lockEventListeners = listeners( eventListenerRegistry, EventType.LOCK );
this.persistEventListeners = listeners( eventListenerRegistry, EventType.PERSIST );
this.persistOnFlushEventListeners = listeners( eventListenerRegistry, EventType.PERSIST_ONFLUSH );
this.mergeEventListeners = listeners( eventListenerRegistry, EventType.MERGE );
this.deleteEventListeners = listeners( eventListenerRegistry, EventType.DELETE );
this.loadEventListeners = listeners( eventListenerRegistry, EventType.LOAD );
this.refreshEventListeners = listeners( eventListenerRegistry, EventType.REFRESH );
this.replicateEventListeners = listeners( eventListenerRegistry, EventType.REPLICATE );
this.autoFlushEventListeners = listeners( eventListenerRegistry, EventType.AUTO_FLUSH );
this.dirtyCheckEventListeners = listeners( eventListenerRegistry, EventType.DIRTY_CHECK );
this.flushEventListeners = listeners( eventListenerRegistry, EventType.FLUSH );
this.initCollectionEventListeners = listeners( eventListenerRegistry, EventType.INIT_COLLECTION );
this.resolveNaturalIdEventListeners = listeners( eventListenerRegistry, EventType.RESOLVE_NATURAL_ID );
this.eventListenerGroup_AUTO_FLUSH = listeners( eventListenerRegistry, EventType.AUTO_FLUSH );
this.eventListenerGroup_CLEAR = listeners( eventListenerRegistry, EventType.CLEAR );
this.eventListenerGroup_DELETE = listeners( eventListenerRegistry, EventType.DELETE );
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_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_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 );
//Other highly useful constants:
this.dialect = jdbcServices.getJdbcEnvironment().getDialect();
@ -176,80 +176,8 @@ final class FastSessionServices {
this.defaultSessionEventListeners = sessionFactoryOptions.getBaselineSessionEventsListenerBuilder();
}
Iterable<ClearEventListener> getClearEventListeners() {
return clearEventListeners;
}
Iterable<EvictEventListener> getEvictEventListeners() {
return this.evictEventListeners;
}
Iterable<DirtyCheckEventListener> getDirtyCheckEventListeners() {
return this.dirtyCheckEventListeners;
}
Iterable<SaveOrUpdateEventListener> getSaveUpdateEventListeners() {
return this.saveUpdateEventListeners;
}
Iterable<SaveOrUpdateEventListener> getSaveEventListeners() {
return this.saveEventListeners;
}
Iterable<SaveOrUpdateEventListener> getUpdateEventListeners() {
return this.updateEventListeners;
}
Iterable<LockEventListener> getLockEventListeners() {
return this.lockEventListeners;
}
Iterable<PersistEventListener> getPersistEventListeners() {
return persistEventListeners;
}
Iterable<FlushEventListener> getFlushEventListeners() {
return flushEventListeners;
}
Iterable<PersistEventListener> getPersistOnFlushEventListeners() {
return persistOnFlushEventListeners;
}
Iterable<InitializeCollectionEventListener> getInitCollectionEventListeners() {
return initCollectionEventListeners;
}
Iterable<LoadEventListener> getLoadEventListeners() {
return loadEventListeners;
}
Iterable<MergeEventListener> getMergeEventListeners() {
return mergeEventListeners;
}
Iterable<RefreshEventListener> getRefreshEventListeners() {
return refreshEventListeners;
}
Iterable<DeleteEventListener> getDeleteEventListeners() {
return deleteEventListeners;
}
Iterable<AutoFlushEventListener> getAutoFlushEventListeners() {
return autoFlushEventListeners;
}
Iterable<ReplicateEventListener> getReplicateEventListeners() {
return replicateEventListeners;
}
Iterable<ResolveNaturalIdEventListener> getResolveNaturalIdEventListeners() {
return resolveNaturalIdEventListeners;
}
private static <T> Iterable<T> listeners(EventListenerRegistry elr, EventType<T> type) {
return elr.getEventListenerGroup( type ).listeners();
private static <T> EventListenerGroup<T> listeners(EventListenerRegistry elr, EventType<T> type) {
return elr.getEventListenerGroup( type );
}
SqlTypeDescriptor remapSqlTypeDescriptor(SqlTypeDescriptor sqlTypeDescriptor) {

View File

@ -307,13 +307,12 @@ public final class SessionImpl
persistenceContext.clear();
actionQueue.clear();
final ClearEvent event = new ClearEvent( this );
for ( ClearEventListener listener : fastSessionServices.getClearEventListeners() ) {
listener.onClear( event );
}
fastSessionServices.eventListenerGroup_CLEAR.fireLazyEventOnEachListener( this::createClearEvent, ClearEventListener::onClear );
}
private ClearEvent createClearEvent() {
return new ClearEvent( this );
}
@Override
@SuppressWarnings("StatementWithEmptyBody")
@ -578,13 +577,11 @@ public final class SessionImpl
fireSaveOrUpdate( new SaveOrUpdateEvent( entityName, obj, this ) );
}
private void fireSaveOrUpdate(SaveOrUpdateEvent event) {
private void fireSaveOrUpdate(final SaveOrUpdateEvent event) {
checkOpen();
checkTransactionSynchStatus();
checkNoUnresolvedActionsBeforeOperation();
for ( SaveOrUpdateEventListener listener : fastSessionServices.getSaveUpdateEventListeners() ) {
listener.onSaveOrUpdate( event );
}
fastSessionServices.eventListenerGroup_SAVE_UPDATE.fireEventOnEachListener( event, SaveOrUpdateEventListener::onSaveOrUpdate );
checkNoUnresolvedActionsAfterOperation();
}
@ -600,13 +597,11 @@ public final class SessionImpl
return fireSave( new SaveOrUpdateEvent( entityName, object, this ) );
}
private Serializable fireSave(SaveOrUpdateEvent event) {
private Serializable fireSave(final SaveOrUpdateEvent event) {
checkOpen();
checkTransactionSynchStatus();
checkNoUnresolvedActionsBeforeOperation();
for ( SaveOrUpdateEventListener listener : fastSessionServices.getSaveEventListeners() ) {
listener.onSaveOrUpdate( event );
}
fastSessionServices.eventListenerGroup_SAVE.fireEventOnEachListener( event, SaveOrUpdateEventListener::onSaveOrUpdate );
checkNoUnresolvedActionsAfterOperation();
return event.getResultId();
}
@ -628,9 +623,7 @@ public final class SessionImpl
checkOpen();
checkTransactionSynchStatus();
checkNoUnresolvedActionsBeforeOperation();
for ( SaveOrUpdateEventListener listener : fastSessionServices.getUpdateEventListeners() ) {
listener.onSaveOrUpdate( event );
}
fastSessionServices.eventListenerGroup_UPDATE.fireEventOnEachListener( event, SaveOrUpdateEventListener::onSaveOrUpdate );
checkNoUnresolvedActionsAfterOperation();
}
@ -663,13 +656,10 @@ public final class SessionImpl
private void fireLock(LockEvent event) {
checkOpen();
pulseTransactionCoordinator();
for ( LockEventListener listener : fastSessionServices.getLockEventListeners() ) {
listener.onLock( event );
}
fastSessionServices.eventListenerGroup_LOCK.fireEventOnEachListener( event, LockEventListener::onLock );
delayedAfterCompletion();
}
// persist() operations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@Override
@ -690,14 +680,12 @@ public final class SessionImpl
firePersist( copiedAlready, new PersistEvent( entityName, object, this ) );
}
private void firePersist(PersistEvent event) {
private void firePersist(final PersistEvent event) {
try {
checkTransactionSynchStatus();
checkNoUnresolvedActionsBeforeOperation();
for ( PersistEventListener listener : fastSessionServices.getPersistEventListeners() ) {
listener.onPersist( event );
}
fastSessionServices.eventListenerGroup_PERSIST.fireEventOnEachListener( event, PersistEventListener::onPersist );
}
catch (MappingException e) {
throw getExceptionConverter().convert( new IllegalArgumentException( e.getMessage() ) );
@ -715,13 +703,13 @@ public final class SessionImpl
}
}
private void firePersist(Map copiedAlready, PersistEvent event) {
private void firePersist(final Map copiedAlready, final PersistEvent event) {
pulseTransactionCoordinator();
try {
for ( PersistEventListener listener : fastSessionServices.getPersistEventListeners() ) {
listener.onPersist( event, copiedAlready );
}
//Uses a capturing lambda in this case as we need to carry the additional Map parameter:
fastSessionServices.eventListenerGroup_PERSIST
.fireEventOnEachListener( event, (l, e) -> l.onPersist( e, copiedAlready ) );
}
catch ( MappingException e ) {
throw getExceptionConverter().convert( new IllegalArgumentException( e.getMessage() ) ) ;
@ -752,22 +740,18 @@ public final class SessionImpl
firePersistOnFlush( copiedAlready, new PersistEvent( entityName, object, this ) );
}
private void firePersistOnFlush(Map copiedAlready, PersistEvent event) {
private void firePersistOnFlush(final Map copiedAlready, final PersistEvent event) {
checkOpenOrWaitingForAutoClose();
pulseTransactionCoordinator();
for ( PersistEventListener listener : fastSessionServices.getPersistOnFlushEventListeners() ) {
listener.onPersist( event, copiedAlready );
}
fastSessionServices.eventListenerGroup_PERSIST_ONFLUSH.fireEventOnEachListener( event, (l,e) -> l.onPersist( e, copiedAlready ) );
delayedAfterCompletion();
}
private void firePersistOnFlush(PersistEvent event) {
private void firePersistOnFlush(final PersistEvent event) {
checkOpen();
checkTransactionSynchStatus();
checkNoUnresolvedActionsBeforeOperation();
for ( PersistEventListener listener : fastSessionServices.getPersistOnFlushEventListeners() ) {
listener.onPersist( event );
}
fastSessionServices.eventListenerGroup_PERSIST_ONFLUSH.fireEventOnEachListener( event, PersistEventListener::onPersist );
checkNoUnresolvedActionsAfterOperation();
}
@ -796,9 +780,7 @@ public final class SessionImpl
try {
checkTransactionSynchStatus();
checkNoUnresolvedActionsBeforeOperation();
for ( MergeEventListener listener : fastSessionServices.getMergeEventListeners() ) {
listener.onMerge( event );
}
fastSessionServices.eventListenerGroup_MERGE.fireEventOnEachListener( event, MergeEventListener::onMerge );
checkNoUnresolvedActionsAfterOperation();
}
catch ( ObjectDeletedException sse ) {
@ -815,12 +797,10 @@ public final class SessionImpl
return event.getResult();
}
private void fireMerge(Map copiedAlready, MergeEvent event) {
private void fireMerge(final Map copiedAlready, final MergeEvent event) {
try {
pulseTransactionCoordinator();
for ( MergeEventListener listener : fastSessionServices.getMergeEventListeners() ) {
listener.onMerge( event, copiedAlready );
}
fastSessionServices.eventListenerGroup_MERGE.fireEventOnEachListener( event, (l,e) -> l.onMerge( e, copiedAlready ) );
}
catch ( ObjectDeletedException sse ) {
throw getExceptionConverter().convert( new IllegalArgumentException( sse ) );
@ -905,12 +885,10 @@ public final class SessionImpl
}
}
private void fireDelete(DeleteEvent event) {
private void fireDelete(final DeleteEvent event) {
try{
pulseTransactionCoordinator();
for ( DeleteEventListener listener : fastSessionServices.getDeleteEventListeners() ) {
listener.onDelete( event );
}
fastSessionServices.eventListenerGroup_DELETE.fireEventOnEachListener( event, DeleteEventListener::onDelete );
}
catch ( ObjectDeletedException sse ) {
throw getExceptionConverter().convert( new IllegalArgumentException( sse ) );
@ -927,12 +905,10 @@ public final class SessionImpl
}
}
private void fireDelete(DeleteEvent event, Set transientEntities) {
private void fireDelete(final DeleteEvent event, final Set transientEntities) {
try{
pulseTransactionCoordinator();
for ( DeleteEventListener listener : fastSessionServices.getDeleteEventListeners() ) {
listener.onDelete( event, transientEntities );
}
fastSessionServices.eventListenerGroup_DELETE.fireEventOnEachListener( event, (l,e) -> l.onDelete( e, transientEntities ) );
}
catch ( ObjectDeletedException sse ) {
throw getExceptionConverter().convert( new IllegalArgumentException( sse ) );
@ -1205,19 +1181,15 @@ public final class SessionImpl
// so to skip the session open, transaction synch, etc.. checks,
// which have been proven to be not particularly cheap:
// it seems they prevent these hot methods from being inlined.
private void fireLoadNoChecks(LoadEvent event, LoadType loadType) {
private void fireLoadNoChecks(final LoadEvent event, final LoadType loadType) {
pulseTransactionCoordinator();
for ( LoadEventListener listener : fastSessionServices.getLoadEventListeners() ) {
listener.onLoad( event, loadType );
}
fastSessionServices.eventListenerGroup_LOAD.fireEventOnEachListener( event, (l,e) -> l.onLoad( e, loadType ) );
}
private void fireResolveNaturalId(ResolveNaturalIdEvent event) {
private void fireResolveNaturalId(final ResolveNaturalIdEvent event) {
checkOpenOrWaitingForAutoClose();
pulseTransactionCoordinator();
for ( ResolveNaturalIdEventListener listener : fastSessionServices.getResolveNaturalIdEventListeners() ) {
listener.onResolveNaturalId( event );
}
fastSessionServices.eventListenerGroup_RESOLVE_NATURAL_ID.fireEventOnEachListener( event, ResolveNaturalIdEventListener::onResolveNaturalId );
delayedAfterCompletion();
}
@ -1260,7 +1232,7 @@ public final class SessionImpl
fireRefresh( refreshedAlready, new RefreshEvent( entityName, object, this ) );
}
private void fireRefresh(RefreshEvent event) {
private void fireRefresh(final RefreshEvent event) {
try {
if ( !getSessionFactory().getSessionFactoryOptions().isAllowRefreshDetachedEntity() ) {
if ( event.getEntityName() != null ) {
@ -1275,9 +1247,7 @@ public final class SessionImpl
}
}
pulseTransactionCoordinator();
for ( RefreshEventListener listener : fastSessionServices.getRefreshEventListeners() ) {
listener.onRefresh( event );
}
fastSessionServices.eventListenerGroup_REFRESH.fireEventOnEachListener( event, RefreshEventListener::onRefresh );
}
catch (RuntimeException e) {
if ( !getSessionFactory().getSessionFactoryOptions().isJpaBootstrap() ) {
@ -1293,12 +1263,10 @@ public final class SessionImpl
}
}
private void fireRefresh(Map refreshedAlready, RefreshEvent event) {
private void fireRefresh(final Map refreshedAlready, final RefreshEvent event) {
try {
pulseTransactionCoordinator();
for ( RefreshEventListener listener : fastSessionServices.getRefreshEventListeners() ) {
listener.onRefresh( event, refreshedAlready );
}
fastSessionServices.eventListenerGroup_REFRESH.fireEventOnEachListener( event, (l,e) -> l.onRefresh( e, refreshedAlready ) );
}
catch (RuntimeException e) {
throw getExceptionConverter().convert( e );
@ -1322,12 +1290,10 @@ public final class SessionImpl
fireReplicate( new ReplicateEvent( entityName, obj, replicationMode, this ) );
}
private void fireReplicate(ReplicateEvent event) {
private void fireReplicate(final ReplicateEvent event) {
checkOpen();
pulseTransactionCoordinator();
for ( ReplicateEventListener listener : fastSessionServices.getReplicateEventListeners() ) {
listener.onReplicate( event );
}
fastSessionServices.eventListenerGroup_REPLICATE.fireEventOnEachListener( event, ReplicateEventListener::onReplicate );
delayedAfterCompletion();
}
@ -1340,15 +1306,10 @@ public final class SessionImpl
*/
@Override
public void evict(Object object) throws HibernateException {
fireEvict( new EvictEvent( object, this ) );
}
private void fireEvict(EvictEvent event) {
checkOpen();
pulseTransactionCoordinator();
for ( EvictEventListener listener : fastSessionServices.getEvictEventListeners() ) {
listener.onEvict( event );
}
final EvictEvent event = new EvictEvent( object, this );
fastSessionServices.eventListenerGroup_EVICT.fireEventOnEachListener( event, EvictEventListener::onEvict );
delayedAfterCompletion();
}
@ -1363,9 +1324,7 @@ public final class SessionImpl
return false;
}
AutoFlushEvent event = new AutoFlushEvent( querySpaces, this );
for ( AutoFlushEventListener listener : fastSessionServices.getAutoFlushEventListeners() ) {
listener.onAutoFlush( event );
}
fastSessionServices.eventListenerGroup_AUTO_FLUSH.fireEventOnEachListener( event, AutoFlushEventListener::onAutoFlush );
return event.isFlushRequired();
}
@ -1379,9 +1338,7 @@ public final class SessionImpl
return true;
}
DirtyCheckEvent event = new DirtyCheckEvent( this );
for ( DirtyCheckEventListener listener : fastSessionServices.getDirtyCheckEventListeners() ) {
listener.onDirtyCheck( event );
}
fastSessionServices.eventListenerGroup_DIRTY_CHECK.fireEventOnEachListener( event, DirtyCheckEventListener::onDirtyCheck );
delayedAfterCompletion();
return event.isDirty();
}
@ -1401,11 +1358,8 @@ public final class SessionImpl
throw new HibernateException( "Flush during cascade is dangerous" );
}
FlushEvent flushEvent = new FlushEvent( this );
for ( FlushEventListener listener : fastSessionServices.getFlushEventListeners() ) {
listener.onFlush( flushEvent );
}
FlushEvent event = new FlushEvent( this );
fastSessionServices.eventListenerGroup_FLUSH.fireEventOnEachListener( event, FlushEventListener::onFlush );
delayedAfterCompletion();
}
catch ( RuntimeException e ) {
@ -2206,9 +2160,7 @@ public final class SessionImpl
checkOpenOrWaitingForAutoClose();
pulseTransactionCoordinator();
InitializeCollectionEvent event = new InitializeCollectionEvent( collection, this );
for ( InitializeCollectionEventListener listener : fastSessionServices.getInitCollectionEventListeners() ) {
listener.onInitializeCollection( event );
}
fastSessionServices.eventListenerGroup_INIT_COLLECTION.fireEventOnEachListener( event, InitializeCollectionEventListener::onInitializeCollection );
delayedAfterCompletion();
}