HHH-13565 Review allocations for default SessionEventListener instances
This commit is contained in:
parent
4b2f056a63
commit
269d5f8358
|
@ -7,6 +7,7 @@
|
|||
package org.hibernate.cfg;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
|
@ -17,6 +18,9 @@ import org.hibernate.engine.internal.StatisticalLoggingSessionEventListener;
|
|||
* @author Steve Ebersole
|
||||
*/
|
||||
public class BaselineSessionEventsListenerBuilder {
|
||||
|
||||
private static final SessionEventListener[] EMPTY = new SessionEventListener[0];
|
||||
|
||||
private boolean logSessionMetrics;
|
||||
private Class<? extends SessionEventListener> autoListener;
|
||||
|
||||
|
@ -33,6 +37,10 @@ public class BaselineSessionEventsListenerBuilder {
|
|||
}
|
||||
|
||||
@SuppressWarnings("UnusedDeclaration")
|
||||
/**
|
||||
* @deprecated this method will be removed as this builder should become immutable
|
||||
*/
|
||||
@Deprecated
|
||||
public void setLogSessionMetrics(boolean logSessionMetrics) {
|
||||
this.logSessionMetrics = logSessionMetrics;
|
||||
}
|
||||
|
@ -43,26 +51,59 @@ public class BaselineSessionEventsListenerBuilder {
|
|||
}
|
||||
|
||||
@SuppressWarnings("UnusedDeclaration")
|
||||
/**
|
||||
* @deprecated this method will be removed as this builder should become immutable
|
||||
*/
|
||||
@Deprecated
|
||||
public void setAutoListener(Class<? extends SessionEventListener> autoListener) {
|
||||
this.autoListener = autoListener;
|
||||
}
|
||||
|
||||
public List<SessionEventListener> buildBaselineList() {
|
||||
List<SessionEventListener> list = new ArrayList<SessionEventListener>();
|
||||
if ( logSessionMetrics && StatisticalLoggingSessionEventListener.isLoggingEnabled() ) {
|
||||
list.add( new StatisticalLoggingSessionEventListener() );
|
||||
}
|
||||
if ( autoListener != null ) {
|
||||
try {
|
||||
list.add( autoListener.newInstance() );
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new HibernateException(
|
||||
"Unable to instantiate specified auto SessionEventListener : " + autoListener.getName(),
|
||||
e
|
||||
);
|
||||
}
|
||||
}
|
||||
final SessionEventListener[] sessionEventListeners = buildBaseline();
|
||||
//Capacity: needs to hold at least all elements from the baseline, but also expect to add a little more later.
|
||||
ArrayList<SessionEventListener> list = new ArrayList<>( sessionEventListeners.length + 3 );
|
||||
Collections.addAll( list, sessionEventListeners );
|
||||
return list;
|
||||
}
|
||||
|
||||
public SessionEventListener[] buildBaseline() {
|
||||
final boolean addStats = logSessionMetrics && StatisticalLoggingSessionEventListener.isLoggingEnabled();
|
||||
final boolean addAutoListener = autoListener != null;
|
||||
final SessionEventListener[] arr;
|
||||
if ( addStats && addAutoListener ) {
|
||||
arr = new SessionEventListener[2];
|
||||
arr[0] = buildStatsListener();
|
||||
arr[1] = buildAutoListener( autoListener );
|
||||
}
|
||||
else if ( !addStats && !addAutoListener ) {
|
||||
arr = EMPTY;
|
||||
}
|
||||
else if ( !addStats && addAutoListener ) {
|
||||
arr = new SessionEventListener[1];
|
||||
arr[0] = buildAutoListener( autoListener );
|
||||
}
|
||||
else { //Last case: if ( addStats && !addAutoListener )
|
||||
arr = new SessionEventListener[1];
|
||||
arr[0] = buildStatsListener();
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
|
||||
private static SessionEventListener buildAutoListener(final Class<? extends SessionEventListener> autoListener) {
|
||||
try {
|
||||
return autoListener.newInstance();
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new HibernateException(
|
||||
"Unable to instantiate specified auto SessionEventListener : " + autoListener.getName(),
|
||||
e
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private static SessionEventListener buildStatsListener() {
|
||||
return new StatisticalLoggingSessionEventListener();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -7,8 +7,8 @@
|
|||
package org.hibernate.engine.internal;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.hibernate.SessionEventListener;
|
||||
import org.hibernate.engine.spi.SessionEventListenerManager;
|
||||
|
@ -17,255 +17,269 @@ import org.hibernate.engine.spi.SessionEventListenerManager;
|
|||
* @author Steve Ebersole
|
||||
*/
|
||||
public class SessionEventListenerManagerImpl implements SessionEventListenerManager, Serializable {
|
||||
private List<SessionEventListener> listenerList;
|
||||
|
||||
private SessionEventListener[] listeners;
|
||||
|
||||
public SessionEventListenerManagerImpl(SessionEventListener... initialListener) {
|
||||
//no need for defensive copies until the array is mutated:
|
||||
this.listeners = initialListener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addListener(SessionEventListener... listeners) {
|
||||
if ( listenerList == null ) {
|
||||
listenerList = new ArrayList<>();
|
||||
public void addListener(final SessionEventListener... additionalListeners) {
|
||||
Objects.requireNonNull( additionalListeners );
|
||||
final SessionEventListener[] existing = this.listeners;
|
||||
if ( existing == null ) {
|
||||
//Make a defensive copy as this array can be tracked back to API (user code)
|
||||
this.listeners = Arrays.copyOf( additionalListeners, additionalListeners.length );
|
||||
}
|
||||
else {
|
||||
// Resize our existing array and add the new listeners
|
||||
final SessionEventListener[] newlist = new SessionEventListener[ existing.length + additionalListeners.length ];
|
||||
System.arraycopy( existing, 0, newlist, 0, existing.length );
|
||||
System.arraycopy( additionalListeners, 0, newlist, existing.length, additionalListeners.length );
|
||||
this.listeners = newlist;
|
||||
}
|
||||
|
||||
java.util.Collections.addAll( listenerList, listeners );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void transactionCompletion(boolean successful) {
|
||||
if ( listenerList == null ) {
|
||||
if ( listeners == null ) {
|
||||
return;
|
||||
}
|
||||
|
||||
for ( SessionEventListener listener : listenerList ) {
|
||||
for ( SessionEventListener listener : listeners ) {
|
||||
listener.transactionCompletion( successful );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jdbcConnectionAcquisitionStart() {
|
||||
if ( listenerList == null ) {
|
||||
if ( listeners == null ) {
|
||||
return;
|
||||
}
|
||||
|
||||
for ( SessionEventListener listener : listenerList ) {
|
||||
for ( SessionEventListener listener : listeners ) {
|
||||
listener.jdbcConnectionAcquisitionStart();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jdbcConnectionAcquisitionEnd() {
|
||||
if ( listenerList == null ) {
|
||||
if ( listeners == null ) {
|
||||
return;
|
||||
}
|
||||
|
||||
for ( SessionEventListener listener : listenerList ) {
|
||||
for ( SessionEventListener listener : listeners ) {
|
||||
listener.jdbcConnectionAcquisitionEnd();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jdbcConnectionReleaseStart() {
|
||||
if ( listenerList == null ) {
|
||||
if ( listeners == null ) {
|
||||
return;
|
||||
}
|
||||
|
||||
for ( SessionEventListener listener : listenerList ) {
|
||||
for ( SessionEventListener listener : listeners ) {
|
||||
listener.jdbcConnectionReleaseStart();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jdbcConnectionReleaseEnd() {
|
||||
if ( listenerList == null ) {
|
||||
if ( listeners == null ) {
|
||||
return;
|
||||
}
|
||||
|
||||
for ( SessionEventListener listener : listenerList ) {
|
||||
for ( SessionEventListener listener : listeners ) {
|
||||
listener.jdbcConnectionReleaseEnd();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jdbcPrepareStatementStart() {
|
||||
if ( listenerList == null ) {
|
||||
if ( listeners == null ) {
|
||||
return;
|
||||
}
|
||||
|
||||
for ( SessionEventListener listener : listenerList ) {
|
||||
for ( SessionEventListener listener : listeners ) {
|
||||
listener.jdbcPrepareStatementStart();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jdbcPrepareStatementEnd() {
|
||||
if ( listenerList == null ) {
|
||||
if ( listeners == null ) {
|
||||
return;
|
||||
}
|
||||
|
||||
for ( SessionEventListener listener : listenerList ) {
|
||||
for ( SessionEventListener listener : listeners ) {
|
||||
listener.jdbcPrepareStatementEnd();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jdbcExecuteStatementStart() {
|
||||
if ( listenerList == null ) {
|
||||
if ( listeners == null ) {
|
||||
return;
|
||||
}
|
||||
|
||||
for ( SessionEventListener listener : listenerList ) {
|
||||
for ( SessionEventListener listener : listeners ) {
|
||||
listener.jdbcExecuteStatementStart();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jdbcExecuteStatementEnd() {
|
||||
if ( listenerList == null ) {
|
||||
if ( listeners == null ) {
|
||||
return;
|
||||
}
|
||||
|
||||
for ( SessionEventListener listener : listenerList ) {
|
||||
for ( SessionEventListener listener : listeners ) {
|
||||
listener.jdbcExecuteStatementEnd();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jdbcExecuteBatchStart() {
|
||||
if ( listenerList == null ) {
|
||||
if ( listeners == null ) {
|
||||
return;
|
||||
}
|
||||
|
||||
for ( SessionEventListener listener : listenerList ) {
|
||||
for ( SessionEventListener listener : listeners ) {
|
||||
listener.jdbcExecuteBatchStart();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void jdbcExecuteBatchEnd() {
|
||||
if ( listenerList == null ) {
|
||||
if ( listeners == null ) {
|
||||
return;
|
||||
}
|
||||
|
||||
for ( SessionEventListener listener : listenerList ) {
|
||||
for ( SessionEventListener listener : listeners ) {
|
||||
listener.jdbcExecuteBatchEnd();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cachePutStart() {
|
||||
if ( listenerList == null ) {
|
||||
if ( listeners == null ) {
|
||||
return;
|
||||
}
|
||||
|
||||
for ( SessionEventListener listener : listenerList ) {
|
||||
for ( SessionEventListener listener : listeners ) {
|
||||
listener.cachePutStart();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cachePutEnd() {
|
||||
if ( listenerList == null ) {
|
||||
if ( listeners == null ) {
|
||||
return;
|
||||
}
|
||||
|
||||
for ( SessionEventListener listener : listenerList ) {
|
||||
for ( SessionEventListener listener : listeners ) {
|
||||
listener.cachePutEnd();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cacheGetStart() {
|
||||
if ( listenerList == null ) {
|
||||
if ( listeners == null ) {
|
||||
return;
|
||||
}
|
||||
|
||||
for ( SessionEventListener listener : listenerList ) {
|
||||
for ( SessionEventListener listener : listeners ) {
|
||||
listener.cacheGetStart();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cacheGetEnd(boolean hit) {
|
||||
if ( listenerList == null ) {
|
||||
if ( listeners == null ) {
|
||||
return;
|
||||
}
|
||||
|
||||
for ( SessionEventListener listener : listenerList ) {
|
||||
for ( SessionEventListener listener : listeners ) {
|
||||
listener.cacheGetEnd( hit );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flushStart() {
|
||||
if ( listenerList == null ) {
|
||||
if ( listeners == null ) {
|
||||
return;
|
||||
}
|
||||
|
||||
for ( SessionEventListener listener : listenerList ) {
|
||||
for ( SessionEventListener listener : listeners ) {
|
||||
listener.flushStart();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flushEnd(int numberOfEntities, int numberOfCollections) {
|
||||
if ( listenerList == null ) {
|
||||
if ( listeners == null ) {
|
||||
return;
|
||||
}
|
||||
|
||||
for ( SessionEventListener listener : listenerList ) {
|
||||
for ( SessionEventListener listener : listeners ) {
|
||||
listener.flushEnd( numberOfEntities, numberOfCollections );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void partialFlushStart() {
|
||||
if ( listenerList == null ) {
|
||||
if ( listeners == null ) {
|
||||
return;
|
||||
}
|
||||
|
||||
for ( SessionEventListener listener : listenerList ) {
|
||||
for ( SessionEventListener listener : listeners ) {
|
||||
listener.partialFlushStart();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void partialFlushEnd(int numberOfEntities, int numberOfCollections) {
|
||||
if ( listenerList == null ) {
|
||||
if ( listeners == null ) {
|
||||
return;
|
||||
}
|
||||
|
||||
for ( SessionEventListener listener : listenerList ) {
|
||||
for ( SessionEventListener listener : listeners ) {
|
||||
listener.partialFlushEnd( numberOfEntities, numberOfCollections );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dirtyCalculationStart() {
|
||||
if ( listenerList == null ) {
|
||||
if ( listeners == null ) {
|
||||
return;
|
||||
}
|
||||
|
||||
for ( SessionEventListener listener : listenerList ) {
|
||||
for ( SessionEventListener listener : listeners ) {
|
||||
listener.dirtyCalculationStart();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dirtyCalculationEnd(boolean dirty) {
|
||||
if ( listenerList == null ) {
|
||||
if ( listeners == null ) {
|
||||
return;
|
||||
}
|
||||
|
||||
for ( SessionEventListener listener : listenerList ) {
|
||||
for ( SessionEventListener listener : listeners ) {
|
||||
listener.dirtyCalculationEnd( dirty );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void end() {
|
||||
if ( listenerList == null ) {
|
||||
if ( listeners == null ) {
|
||||
return;
|
||||
}
|
||||
|
||||
for ( SessionEventListener listener : listenerList ) {
|
||||
for ( SessionEventListener listener : listeners ) {
|
||||
listener.end();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,6 +32,7 @@ import org.hibernate.HibernateException;
|
|||
import org.hibernate.Interceptor;
|
||||
import org.hibernate.LockMode;
|
||||
import org.hibernate.MultiTenancyStrategy;
|
||||
import org.hibernate.SessionEventListener;
|
||||
import org.hibernate.SessionException;
|
||||
import org.hibernate.Transaction;
|
||||
import org.hibernate.boot.registry.classloading.spi.ClassLoadingException;
|
||||
|
@ -136,7 +137,7 @@ public abstract class AbstractSharedSessionContract implements SharedSessionCont
|
|||
protected boolean waitingForAutoClose;
|
||||
|
||||
// transient & non-final for Serialization purposes - ugh
|
||||
private transient SessionEventListenerManagerImpl sessionEventsManager = new SessionEventListenerManagerImpl();
|
||||
private transient SessionEventListenerManagerImpl sessionEventsManager;
|
||||
private transient EntityNameResolver entityNameResolver;
|
||||
|
||||
private Integer jdbcBatchSize;
|
||||
|
@ -168,6 +169,13 @@ public abstract class AbstractSharedSessionContract implements SharedSessionCont
|
|||
|
||||
this.interceptor = interpret( options.getInterceptor() );
|
||||
this.jdbcTimeZone = options.getJdbcTimeZone();
|
||||
final List<SessionEventListener> customSessionEventListener = options.getCustomSessionEventListener();
|
||||
if ( customSessionEventListener == null ) {
|
||||
sessionEventsManager = new SessionEventListenerManagerImpl( fastSessionServices.defaultSessionEventListeners.buildBaseline() );
|
||||
}
|
||||
else {
|
||||
sessionEventsManager = new SessionEventListenerManagerImpl( customSessionEventListener.toArray( new SessionEventListener[0] ) );
|
||||
}
|
||||
|
||||
final StatementInspector statementInspector = interpret( options.getStatementInspector() );
|
||||
this.jdbcSessionContext = new JdbcSessionContextImpl( this, statementInspector, fastSessionServices );
|
||||
|
@ -1190,7 +1198,6 @@ public abstract class AbstractSharedSessionContract implements SharedSessionCont
|
|||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// Step 1 :: read back non-transient state...
|
||||
ois.defaultReadObject();
|
||||
sessionEventsManager = new SessionEventListenerManagerImpl();
|
||||
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// Step 2 :: read back transient state...
|
||||
|
@ -1198,6 +1205,7 @@ public abstract class AbstractSharedSessionContract implements SharedSessionCont
|
|||
|
||||
factory = SessionFactoryImpl.deserialize( ois );
|
||||
fastSessionServices = factory.getFastSessionServices();
|
||||
sessionEventsManager = new SessionEventListenerManagerImpl( fastSessionServices.defaultSessionEventListeners.buildBaseline() );
|
||||
jdbcSessionContext = new JdbcSessionContextImpl( this, (StatementInspector) ois.readObject(), fastSessionServices );
|
||||
jdbcCoordinator = JdbcCoordinatorImpl.deserialize( ois, this );
|
||||
|
||||
|
|
|
@ -10,6 +10,8 @@ import org.hibernate.CacheMode;
|
|||
import org.hibernate.FlushMode;
|
||||
import org.hibernate.LockOptions;
|
||||
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
|
||||
import org.hibernate.boot.spi.SessionFactoryOptions;
|
||||
import org.hibernate.cfg.BaselineSessionEventsListenerBuilder;
|
||||
import org.hibernate.cfg.Environment;
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;
|
||||
|
@ -115,6 +117,7 @@ final class FastSessionServices {
|
|||
final boolean isJtaTransactionAccessible;
|
||||
final CacheMode initialSessionCacheMode;
|
||||
final boolean discardOnClose;
|
||||
final BaselineSessionEventsListenerBuilder defaultSessionEventListeners;
|
||||
|
||||
//Private fields:
|
||||
private final Dialect dialect;
|
||||
|
@ -126,6 +129,7 @@ final class FastSessionServices {
|
|||
Objects.requireNonNull( sf );
|
||||
final ServiceRegistryImplementor sr = sf.getServiceRegistry();
|
||||
final JdbcServices jdbcServices = sf.getJdbcServices();
|
||||
final SessionFactoryOptions sessionFactoryOptions = sf.getSessionFactoryOptions();
|
||||
|
||||
// Pre-compute all iterators on Event listeners:
|
||||
final EventListenerRegistry eventListenerRegistry = sr.getService( EventListenerRegistry.class );
|
||||
|
@ -150,7 +154,7 @@ final class FastSessionServices {
|
|||
|
||||
//Other highly useful constants:
|
||||
this.dialect = jdbcServices.getJdbcEnvironment().getDialect();
|
||||
this.disallowOutOfTransactionUpdateOperations = !sf.getSessionFactoryOptions().isAllowOutOfTransactionUpdateOperations();
|
||||
this.disallowOutOfTransactionUpdateOperations = !sessionFactoryOptions.isAllowOutOfTransactionUpdateOperations();
|
||||
this.useStreamForLobBinding = Environment.useStreamsForBinary() || dialect.useInputStreamToInsertBlob();
|
||||
this.requiresMultiTenantConnectionProvider = sf.getSettings().getMultiTenancyStrategy().requiresMultiTenantConnectionProvider();
|
||||
|
||||
|
@ -167,8 +171,9 @@ final class FastSessionServices {
|
|||
this.defaultCacheStoreMode = determineCacheStoreMode( defaultSessionProperties );
|
||||
this.defaultCacheRetrieveMode = determineCacheRetrieveMode( defaultSessionProperties );
|
||||
this.initialSessionCacheMode = CacheModeHelper.interpretCacheMode( defaultCacheStoreMode, defaultCacheRetrieveMode );
|
||||
this.discardOnClose = sf.getSessionFactoryOptions().isReleaseResourcesOnCloseEnabled();
|
||||
this.discardOnClose = sessionFactoryOptions.isReleaseResourcesOnCloseEnabled();
|
||||
this.defaultJdbcObservers = Collections.singletonList( new ConnectionObserverStatsBridge( sf ) );
|
||||
this.defaultSessionEventListeners = sessionFactoryOptions.getBaselineSessionEventsListenerBuilder();
|
||||
}
|
||||
|
||||
Iterable<ClearEventListener> getClearEventListeners() {
|
||||
|
|
|
@ -9,6 +9,7 @@ package org.hibernate.internal;
|
|||
import java.io.Serializable;
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.hibernate.SessionEventListener;
|
||||
import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;
|
||||
|
@ -24,6 +25,8 @@ public class NonContextualJdbcConnectionAccess implements JdbcConnectionAccess,
|
|||
public NonContextualJdbcConnectionAccess(
|
||||
SessionEventListener listener,
|
||||
ConnectionProvider connectionProvider) {
|
||||
Objects.requireNonNull( listener );
|
||||
Objects.requireNonNull( connectionProvider );
|
||||
this.listener = listener;
|
||||
this.connectionProvider = connectionProvider;
|
||||
}
|
||||
|
|
|
@ -7,10 +7,12 @@
|
|||
package org.hibernate.internal;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.util.List;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import org.hibernate.FlushMode;
|
||||
import org.hibernate.Interceptor;
|
||||
import org.hibernate.SessionEventListener;
|
||||
import org.hibernate.engine.spi.SessionOwner;
|
||||
import org.hibernate.resource.jdbc.spi.PhysicalConnectionHandlingMode;
|
||||
import org.hibernate.resource.jdbc.spi.StatementInspector;
|
||||
|
@ -45,6 +47,12 @@ public interface SessionCreationOptions {
|
|||
|
||||
TimeZone getJdbcTimeZone();
|
||||
|
||||
/**
|
||||
* @return the full list of SessionEventListener if this was customized,
|
||||
* or null if this Session is being created with the default list.
|
||||
*/
|
||||
List<SessionEventListener> getCustomSessionEventListener();
|
||||
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// deprecations
|
||||
|
||||
|
|
|
@ -1156,6 +1156,9 @@ public final class SessionFactoryImpl implements SessionFactoryImplementor {
|
|||
private TimeZone jdbcTimeZone;
|
||||
private boolean queryParametersValidationEnabled;
|
||||
|
||||
// Lazy: defaults can be built by invoking the builder in fastSessionServices.defaultSessionEventListeners
|
||||
// (Need a fresh build for each Session as the listener instances can't be reused across sessions)
|
||||
// Only initialize of the builder is overriding the default.
|
||||
private List<SessionEventListener> listeners;
|
||||
|
||||
//todo : expose setting
|
||||
|
@ -1178,9 +1181,7 @@ public final class SessionFactoryImpl implements SessionFactoryImplementor {
|
|||
tenantIdentifier = currentTenantIdentifierResolver.resolveCurrentTenantIdentifier();
|
||||
}
|
||||
this.jdbcTimeZone = sessionFactoryOptions.getJdbcTimeZone();
|
||||
|
||||
listeners = sessionFactoryOptions.getBaselineSessionEventsListenerBuilder().buildBaselineList();
|
||||
queryParametersValidationEnabled = sessionFactoryOptions.isQueryParametersValidationEnabled();
|
||||
this.queryParametersValidationEnabled = sessionFactoryOptions.isQueryParametersValidationEnabled();
|
||||
}
|
||||
|
||||
|
||||
|
@ -1268,20 +1269,18 @@ public final class SessionFactoryImpl implements SessionFactoryImplementor {
|
|||
return jdbcTimeZone;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SessionEventListener> getCustomSessionEventListener() {
|
||||
return listeners;
|
||||
}
|
||||
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// SessionBuilder
|
||||
|
||||
@Override
|
||||
public Session openSession() {
|
||||
log.tracef( "Opening Hibernate Session. tenant=%s", tenantIdentifier );
|
||||
final SessionImpl session = new SessionImpl( sessionFactory, this );
|
||||
|
||||
final SessionEventListenerManager eventListenerManager = session.getEventListenerManager();
|
||||
for ( SessionEventListener listener : listeners ) {
|
||||
eventListenerManager.addListener( listener );
|
||||
}
|
||||
|
||||
return session;
|
||||
return new SessionImpl( sessionFactory, this );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1377,6 +1376,11 @@ public final class SessionFactoryImpl implements SessionFactoryImplementor {
|
|||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public T eventListeners(SessionEventListener... listeners) {
|
||||
if ( this.listeners == null ) {
|
||||
this.listeners = sessionFactory.getSessionFactoryOptions()
|
||||
.getBaselineSessionEventsListenerBuilder()
|
||||
.buildBaselineList();
|
||||
}
|
||||
Collections.addAll( this.listeners, listeners );
|
||||
return (T) this;
|
||||
}
|
||||
|
@ -1384,7 +1388,13 @@ public final class SessionFactoryImpl implements SessionFactoryImplementor {
|
|||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public T clearEventListeners() {
|
||||
listeners.clear();
|
||||
if ( listeners == null ) {
|
||||
//Needs to initialize explicitly to an empty list as otherwise "null" immplies the default listeners will be applied
|
||||
this.listeners = new ArrayList<SessionEventListener>( 3 );
|
||||
}
|
||||
else {
|
||||
listeners.clear();
|
||||
}
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
|
@ -1484,6 +1494,11 @@ public final class SessionFactoryImpl implements SessionFactoryImplementor {
|
|||
return sessionFactory.getSessionFactoryOptions().getJdbcTimeZone();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SessionEventListener> getCustomSessionEventListener() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SessionOwner getSessionOwner() {
|
||||
return null;
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.event;
|
||||
|
||||
import org.hibernate.BaseSessionEventListener;
|
||||
import org.hibernate.SessionEventListener;
|
||||
import org.hibernate.engine.internal.SessionEventListenerManagerImpl;
|
||||
|
||||
import org.hibernate.testing.junit4.BaseUnitTestCase;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
public class SessionEventListenersManagerTest extends BaseUnitTestCase {
|
||||
|
||||
@Test
|
||||
public void testListenerAppending() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
SessionEventListener a = new TestSessionEventListener( sb , 'a' );
|
||||
SessionEventListener b = new TestSessionEventListener( sb , 'b' );
|
||||
SessionEventListener c = new TestSessionEventListener( sb , 'c' );
|
||||
SessionEventListener d = new TestSessionEventListener( sb , 'd' );
|
||||
SessionEventListenerManagerImpl l = new SessionEventListenerManagerImpl( a, b );
|
||||
l.addListener( c, d );
|
||||
l.dirtyCalculationEnd( true );
|
||||
Assert.assertEquals( "abcd", sb.toString() );
|
||||
l.dirtyCalculationEnd( true );
|
||||
Assert.assertEquals( "abcdabcd", sb.toString() );
|
||||
l.addListener( new TestSessionEventListener( sb , 'e' ) );
|
||||
l.dirtyCalculationEnd( true );
|
||||
Assert.assertEquals( "abcdabcdabcde", sb.toString() );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEmptyListenerAppending() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
SessionEventListenerManagerImpl l = new SessionEventListenerManagerImpl();
|
||||
l.dirtyCalculationEnd( true );
|
||||
Assert.assertEquals( "", sb.toString() );
|
||||
l.addListener( new TestSessionEventListener( sb , 'e' ) );
|
||||
l.dirtyCalculationEnd( true );
|
||||
Assert.assertEquals( "e", sb.toString() );
|
||||
}
|
||||
|
||||
private static class TestSessionEventListener extends BaseSessionEventListener {
|
||||
|
||||
private final StringBuilder sb;
|
||||
private final char theChar;
|
||||
|
||||
public TestSessionEventListener(StringBuilder sb, char theChar) {
|
||||
this.sb = sb;
|
||||
this.theChar = theChar;
|
||||
}
|
||||
|
||||
//Just picking any method. This one is funny..
|
||||
@Override
|
||||
public void dirtyCalculationEnd(boolean dirty) {
|
||||
sb.append( theChar );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue