Skip to content

Commit

Permalink
HHH-10942 - Session not flushing starting from 5.2.0 in Karaf + Aries…
Browse files Browse the repository at this point in the history
… JPA & JTA
  • Loading branch information
dreab8 committed Aug 3, 2016
1 parent d55ade5 commit 109410b
Show file tree
Hide file tree
Showing 12 changed files with 101 additions and 122 deletions.
Expand Up @@ -689,6 +689,14 @@ SessionFactoryBuilder applyEntityTuplizer(


SessionFactoryBuilder allowOutOfTransactionUpdateOperations(boolean allow); SessionFactoryBuilder allowOutOfTransactionUpdateOperations(boolean allow);


/**
* Should resources held by {@link javax.persistence.EntityManager} instance be released immediately on close?
* <p/>
* The other option is to release them as part of an afterQuery-transaction callback.
*
*/
SessionFactoryBuilder enableReleaseResourcesOnCloseEnabled(boolean enable);

/** /**
* Allows unwrapping this builder as another, more specific type. * Allows unwrapping this builder as another, more specific type.
* *
Expand Down
Expand Up @@ -108,6 +108,7 @@
import static org.hibernate.cfg.AvailableSettings.WRAP_RESULT_SETS; import static org.hibernate.cfg.AvailableSettings.WRAP_RESULT_SETS;
import static org.hibernate.cfg.AvailableSettings.ALLOW_UPDATE_OUTSIDE_TRANSACTION; import static org.hibernate.cfg.AvailableSettings.ALLOW_UPDATE_OUTSIDE_TRANSACTION;
import static org.hibernate.engine.config.spi.StandardConverters.BOOLEAN; import static org.hibernate.engine.config.spi.StandardConverters.BOOLEAN;
import static org.hibernate.jpa.AvailableSettings.DISCARD_PC_ON_CLOSE;


/** /**
* @author Gail Badner * @author Gail Badner
Expand Down Expand Up @@ -471,6 +472,12 @@ public SessionFactoryBuilder allowOutOfTransactionUpdateOperations(boolean allow
return this; return this;
} }


@Override
public SessionFactoryBuilder enableReleaseResourcesOnCloseEnabled(boolean enable) {
this.options.releaseResourcesOnCloseEnabled = enable;
return this;
}

@Override @Override
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public <T extends SessionFactoryBuilder> T unwrap(Class<T> type) { public <T extends SessionFactoryBuilder> T unwrap(Class<T> type) {
Expand Down Expand Up @@ -519,6 +526,7 @@ public static class SessionFactoryOptionsStateStandardImpl implements SessionFac
private boolean autoCloseSessionEnabled; private boolean autoCloseSessionEnabled;
private boolean jtaTransactionAccessEnabled; private boolean jtaTransactionAccessEnabled;
private boolean allowOutOfTransactionUpdateOperations; private boolean allowOutOfTransactionUpdateOperations;
private boolean releaseResourcesOnCloseEnabled;


// (JTA) transaction handling // (JTA) transaction handling
private boolean jtaTrackByThread; private boolean jtaTrackByThread;
Expand Down Expand Up @@ -747,11 +755,18 @@ public SessionFactoryOptionsStateStandardImpl(StandardServiceRegistry serviceReg
this.commentsEnabled = ConfigurationHelper.getBoolean( USE_SQL_COMMENTS, configurationSettings ); this.commentsEnabled = ConfigurationHelper.getBoolean( USE_SQL_COMMENTS, configurationSettings );


this.preferUserTransaction = ConfigurationHelper.getBoolean( PREFER_USER_TRANSACTION, configurationSettings, false ); this.preferUserTransaction = ConfigurationHelper.getBoolean( PREFER_USER_TRANSACTION, configurationSettings, false );

this.allowOutOfTransactionUpdateOperations = ConfigurationHelper.getBoolean( this.allowOutOfTransactionUpdateOperations = ConfigurationHelper.getBoolean(
ALLOW_UPDATE_OUTSIDE_TRANSACTION, ALLOW_UPDATE_OUTSIDE_TRANSACTION,
configurationSettings, configurationSettings,
false false
); );

this.releaseResourcesOnCloseEnabled = ConfigurationHelper.getBoolean(
DISCARD_PC_ON_CLOSE,
configurationSettings,
false
);
} }


private static Interceptor determineInterceptor(Map configurationSettings, StrategySelector strategySelector) { private static Interceptor determineInterceptor(Map configurationSettings, StrategySelector strategySelector) {
Expand Down Expand Up @@ -886,6 +901,11 @@ public boolean isAllowOutOfTransactionUpdateOperations() {
return allowOutOfTransactionUpdateOperations; return allowOutOfTransactionUpdateOperations;
} }


@Override
public boolean isReleaseResourcesOnCloseEnabled() {
return releaseResourcesOnCloseEnabled;
}

@Override @Override
public Object getBeanManagerReference() { public Object getBeanManagerReference() {
return beanManagerReference; return beanManagerReference;
Expand Down Expand Up @@ -1181,6 +1201,11 @@ public boolean isAllowOutOfTransactionUpdateOperations() {
return options.isAllowOutOfTransactionUpdateOperations(); return options.isAllowOutOfTransactionUpdateOperations();
} }


@Override
public boolean isReleaseResourcesOnCloseEnabled(){
return options.releaseResourcesOnCloseEnabled;
}

@Override @Override
public Object getBeanManagerReference() { public Object getBeanManagerReference() {
return options.getBeanManagerReference(); return options.getBeanManagerReference();
Expand Down
Expand Up @@ -54,6 +54,7 @@ public class SessionFactoryOptionsImpl implements SessionFactoryOptions {
private boolean jtaTransactionAccessEnabled; private boolean jtaTransactionAccessEnabled;


private boolean allowOutOfTransactionUpdateOperations; private boolean allowOutOfTransactionUpdateOperations;
private boolean releaseResourcesOnCloseEnabled;


// transaction handling // transaction handling
private final boolean jtaTrackByThread; private final boolean jtaTrackByThread;
Expand Down Expand Up @@ -371,6 +372,11 @@ public boolean isAllowOutOfTransactionUpdateOperations() {
return allowOutOfTransactionUpdateOperations; return allowOutOfTransactionUpdateOperations;
} }


@Override
public boolean isReleaseResourcesOnCloseEnabled() {
return releaseResourcesOnCloseEnabled;
}

@Override @Override
public boolean isSecondLevelCacheEnabled() { public boolean isSecondLevelCacheEnabled() {
return secondLevelCacheEnabled; return secondLevelCacheEnabled;
Expand Down
Expand Up @@ -50,6 +50,8 @@ public interface SessionFactoryOptionsState {


boolean isAllowOutOfTransactionUpdateOperations(); boolean isAllowOutOfTransactionUpdateOperations();


boolean isReleaseResourcesOnCloseEnabled();

Object getBeanManagerReference(); Object getBeanManagerReference();


Object getValidatorFactoryReference(); Object getValidatorFactoryReference();
Expand Down
Expand Up @@ -368,6 +368,12 @@ public T allowOutOfTransactionUpdateOperations(boolean allow) {
return getThis(); return getThis();
} }


@Override
public SessionFactoryBuilder enableReleaseResourcesOnCloseEnabled(boolean enable) {
delegate.enableReleaseResourcesOnCloseEnabled( enable );
return getThis();
}

@Override @Override
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public <S extends SessionFactoryBuilder> S unwrap(Class<S> type) { public <S extends SessionFactoryBuilder> S unwrap(Class<S> type) {
Expand Down
Expand Up @@ -218,6 +218,11 @@ public boolean isAllowOutOfTransactionUpdateOperations() {
return delegate.isAllowOutOfTransactionUpdateOperations(); return delegate.isAllowOutOfTransactionUpdateOperations();
} }


@Override
public boolean isReleaseResourcesOnCloseEnabled() {
return delegate.isReleaseResourcesOnCloseEnabled();
}

@Override @Override
public boolean isSecondLevelCacheEnabled() { public boolean isSecondLevelCacheEnabled() {
return delegate.isSecondLevelCacheEnabled(); return delegate.isSecondLevelCacheEnabled();
Expand Down
Expand Up @@ -203,4 +203,6 @@ public interface SessionFactoryOptions {
boolean isProcedureParameterNullPassingEnabled(); boolean isProcedureParameterNullPassingEnabled();


boolean isAllowOutOfTransactionUpdateOperations(); boolean isAllowOutOfTransactionUpdateOperations();

boolean isReleaseResourcesOnCloseEnabled();
} }
Expand Up @@ -114,7 +114,8 @@ public abstract class AbstractSharedSessionContract implements SharedSessionCont


private CacheMode cacheMode; private CacheMode cacheMode;


private boolean closed; protected boolean closed;
protected boolean waitingForAutoClose;


// transient & non-final for Serialization purposes - ugh // transient & non-final for Serialization purposes - ugh
private transient SessionEventListenerManagerImpl sessionEventsManager = new SessionEventListenerManagerImpl(); private transient SessionEventListenerManagerImpl sessionEventsManager = new SessionEventListenerManagerImpl();
Expand Down Expand Up @@ -306,6 +307,7 @@ public void close() {


protected void setClosed() { protected void setClosed() {
closed = true; closed = true;
waitingForAutoClose = false;
cleanupOnClose(); cleanupOnClose();
} }


Expand Down Expand Up @@ -342,6 +344,9 @@ public void markForRollbackOnly() {


@Override @Override
public boolean isTransactionInProgress() { public boolean isTransactionInProgress() {
if ( waitingForAutoClose ) {
return transactionCoordinator.isTransactionActive();
}
return !isClosed() && transactionCoordinator.isTransactionActive(); return !isClosed() && transactionCoordinator.isTransactionActive();
} }


Expand Down
Expand Up @@ -242,6 +242,8 @@ public final class SessionImpl


private transient LoadEvent loadEvent; //cached LoadEvent instance private transient LoadEvent loadEvent; //cached LoadEvent instance


private transient boolean discardOnClose;

public SessionImpl(SessionFactoryImpl factory, SessionCreationOptions options) { public SessionImpl(SessionFactoryImpl factory, SessionCreationOptions options) {
super( factory, options ); super( factory, options );


Expand All @@ -254,6 +256,7 @@ public SessionImpl(SessionFactoryImpl factory, SessionCreationOptions options) {
this.autoClear = options.shouldAutoClear(); this.autoClear = options.shouldAutoClear();
this.autoClose = options.shouldAutoClose(); this.autoClose = options.shouldAutoClose();
this.disallowOutOfTransactionUpdateOperations = !factory.getSessionFactoryOptions().isAllowOutOfTransactionUpdateOperations(); this.disallowOutOfTransactionUpdateOperations = !factory.getSessionFactoryOptions().isAllowOutOfTransactionUpdateOperations();
this.discardOnClose = getFactory().getSessionFactoryOptions().isReleaseResourcesOnCloseEnabled();


if ( options instanceof SharedSessionCreationOptions && ( (SharedSessionCreationOptions) options ).isTransactionCoordinatorShared() ) { if ( options instanceof SharedSessionCreationOptions && ( (SharedSessionCreationOptions) options ).isTransactionCoordinatorShared() ) {
final SharedSessionCreationOptions sharedOptions = (SharedSessionCreationOptions) options; final SharedSessionCreationOptions sharedOptions = (SharedSessionCreationOptions) options;
Expand Down Expand Up @@ -302,6 +305,7 @@ private void applyProperties() {


private void applyEntityManagerSpecificProperties() { private void applyEntityManagerSpecificProperties() {
for ( String key : ENTITY_MANAGER_SPECIFIC_PROPERTIES ) { for ( String key : ENTITY_MANAGER_SPECIFIC_PROPERTIES ) {
final Map<String, Object> properties = getFactory().getProperties();
if ( getFactory().getProperties().containsKey( key ) ) { if ( getFactory().getProperties().containsKey( key ) ) {
this.properties.put( key, getFactory().getProperties().get( key ) ); this.properties.put( key, getFactory().getProperties().get( key ) );
} }
Expand Down Expand Up @@ -398,28 +402,26 @@ public void close() throws HibernateException {


// todo : we want this check if usage is JPA, but not native Hibernate usage // todo : we want this check if usage is JPA, but not native Hibernate usage
if ( getSessionFactory().getSessionFactoryOptions().isJpaBootstrap() ) { if ( getSessionFactory().getSessionFactoryOptions().isJpaBootstrap() ) {
// Original hibernate-entitymanager EM#close behavior
checkSessionFactoryOpen();
checkOpen(); checkOpen();
if ( discardOnClose || !isTransactionInProgress() ) {
super.close();
}
else {
//Otherwise, session auto-close will be enabled by shouldAutoCloseSession().
waitingForAutoClose = true;
closed = true;
}
} }
else {


super.close(); super.close();


if ( getFactory().getStatistics().isStatisticsEnabled() ) { if ( getFactory().getStatistics().isStatisticsEnabled() ) {
getFactory().getStatistics().closeSession(); getFactory().getStatistics().closeSession();
}
} }

// Original hibernate-entitymanager EM#close behavior
// does any of this need to be integrated?
// checkSessionFactoryOpen();
// checkOpen();
//
// if ( discardOnClose || !isTransactionInProgress() ) {
// //close right now
// if ( session != null ) {
// session.close();
// }
// }
// // Otherwise, session auto-close will be enabled by shouldAutoCloseSession().
// open = false;
} }


@Override @Override
Expand All @@ -446,7 +448,7 @@ public boolean isOpen() {
checkSessionFactoryOpen(); checkSessionFactoryOpen();
checkTransactionSynchStatus(); checkTransactionSynchStatus();
try { try {
return !isClosed(); return !isClosed() && !waitingForAutoClose ;
} }
catch (HibernateException he) { catch (HibernateException he) {
throw exceptionConverter.convert( he ); throw exceptionConverter.convert( he );
Expand All @@ -465,17 +467,20 @@ private boolean isFlushModeNever() {
} }


private void managedFlush() { private void managedFlush() {
if ( isClosed() ) { if ( isClosed() && !waitingForAutoClose ) {
log.trace( "Skipping auto-flush due to session closed" ); log.trace( "Skipping auto-flush due to session closed" );
return; return;
} }
log.trace( "Automatically flushing session" ); log.trace( "Automatically flushing session" );
flush(); doFlush();
} }


@Override @Override
public boolean shouldAutoClose() { public boolean shouldAutoClose() {
if ( isClosed() ) { if ( waitingForAutoClose ) {
return true;
}
else if ( isClosed() ) {
return false; return false;
} }
else if ( sessionOwner != null ) { else if ( sessionOwner != null ) {
Expand Down Expand Up @@ -1383,10 +1388,13 @@ public boolean isDirty() throws HibernateException {
@Override @Override
public void flush() throws HibernateException { public void flush() throws HibernateException {
checkOpen(); checkOpen();
doFlush();
}

private void doFlush() {
checkTransactionNeeded(); checkTransactionNeeded();
checkTransactionSynchStatus(); checkTransactionSynchStatus();



try { try {
if ( persistenceContext.getCascadeLevel() > 0 ) { if ( persistenceContext.getCascadeLevel() > 0 ) {
throw new HibernateException( "Flush during cascade is dangerous" ); throw new HibernateException( "Flush during cascade is dangerous" );
Expand Down Expand Up @@ -2224,14 +2232,18 @@ public String toString() {


@Override @Override
public ActionQueue getActionQueue() { public ActionQueue getActionQueue() {
checkOpen(); if ( !waitingForAutoClose ) {
checkOpen();
}
// checkTransactionSynchStatus(); // checkTransactionSynchStatus();
return actionQueue; return actionQueue;
} }


@Override @Override
public PersistenceContext getPersistenceContext() { public PersistenceContext getPersistenceContext() {
checkOpen(); if ( !waitingForAutoClose ) {
checkOpen();
}
// checkTransactionSynchStatus(); // checkTransactionSynchStatus();
return persistenceContext; return persistenceContext;
} }
Expand Down Expand Up @@ -3148,8 +3160,7 @@ public void afterTransactionBegin() {


@Override @Override
public void flushBeforeTransactionCompletion() { public void flushBeforeTransactionCompletion() {
final boolean doFlush = ! isClosed() final boolean doFlush = isTransactionFlushable()
&& isTransactionFlushable()
&& getHibernateFlushMode() != FlushMode.MANUAL; && getHibernateFlushMode() != FlushMode.MANUAL;


try { try {
Expand Down
Expand Up @@ -145,7 +145,6 @@ public class EntityManagerFactoryBuilderImpl implements EntityManagerFactoryBuil
private final StandardServiceRegistry standardServiceRegistry; private final StandardServiceRegistry standardServiceRegistry;
private final ManagedResources managedResources; private final ManagedResources managedResources;
private final MetadataBuilderImplementor metamodelBuilder; private final MetadataBuilderImplementor metamodelBuilder;
private final SettingsImpl settings;


private static class JpaEntityNotFoundDelegate implements EntityNotFoundDelegate, Serializable { private static class JpaEntityNotFoundDelegate implements EntityNotFoundDelegate, Serializable {
/** /**
Expand Down Expand Up @@ -200,7 +199,7 @@ private EntityManagerFactoryBuilderImpl(


// Build the "standard" service registry // Build the "standard" service registry
ssrBuilder.applySettings( configurationValues ); ssrBuilder.applySettings( configurationValues );
this.settings = configure( ssrBuilder ); configure( ssrBuilder );
this.standardServiceRegistry = ssrBuilder.build(); this.standardServiceRegistry = ssrBuilder.build();
configure( standardServiceRegistry, mergedSettings ); configure( standardServiceRegistry, mergedSettings );


Expand Down Expand Up @@ -580,32 +579,24 @@ private CacheRegionDefinition parseCacheRegionDefinitionEntry(String role, Strin
return new CacheRegionDefinition( cacheType, role, usage, region, lazyProperty ); return new CacheRegionDefinition( cacheType, role, usage, region, lazyProperty );
} }


private SettingsImpl configure(StandardServiceRegistryBuilder ssrBuilder) { private void configure(StandardServiceRegistryBuilder ssrBuilder) {
final SettingsImpl settings = new SettingsImpl();


applyJdbcConnectionProperties( ssrBuilder ); applyJdbcConnectionProperties( ssrBuilder );
applyTransactionProperties( ssrBuilder, settings ); applyTransactionProperties( ssrBuilder );


// flush beforeQuery completion validation // flush beforeQuery completion validation
if ( "true".equals( configurationValues.get( Environment.FLUSH_BEFORE_COMPLETION ) ) ) { if ( "true".equals( configurationValues.get( Environment.FLUSH_BEFORE_COMPLETION ) ) ) {
ssrBuilder.applySetting( Environment.FLUSH_BEFORE_COMPLETION, "false" ); ssrBuilder.applySetting( Environment.FLUSH_BEFORE_COMPLETION, "false" );
LOG.definingFlushBeforeCompletionIgnoredInHem( Environment.FLUSH_BEFORE_COMPLETION ); LOG.definingFlushBeforeCompletionIgnoredInHem( Environment.FLUSH_BEFORE_COMPLETION );
} }


final Object value = configurationValues.get( DISCARD_PC_ON_CLOSE );
if ( value != null ) {
settings.setReleaseResourcesOnCloseEnabled( "true".equals( value ) );
}

// final StrategySelector strategySelector = ssrBuilder.getBootstrapServiceRegistry().getService( StrategySelector.class ); // final StrategySelector strategySelector = ssrBuilder.getBootstrapServiceRegistry().getService( StrategySelector.class );
// final Object interceptorSetting = configurationValues.remove( AvailableSettings.SESSION_INTERCEPTOR ); // final Object interceptorSetting = configurationValues.remove( AvailableSettings.SESSION_INTERCEPTOR );
// if ( interceptorSetting != null ) { // if ( interceptorSetting != null ) {
// settings.setSessionInterceptorClass( // settings.setSessionInterceptorClass(
// loadSessionInterceptorClass( interceptorSetting, strategySelector ) // loadSessionInterceptorClass( interceptorSetting, strategySelector )
// ); // );
// } // }

return settings;
} }


private void applyJdbcConnectionProperties(StandardServiceRegistryBuilder ssrBuilder) { private void applyJdbcConnectionProperties(StandardServiceRegistryBuilder ssrBuilder) {
Expand Down Expand Up @@ -646,7 +637,7 @@ else if ( persistenceUnit.getNonJtaDataSource() != null ) {
} }
} }


private void applyTransactionProperties(StandardServiceRegistryBuilder ssrBuilder, SettingsImpl settings) { private void applyTransactionProperties(StandardServiceRegistryBuilder ssrBuilder) {
PersistenceUnitTransactionType txnType = PersistenceUnitTransactionTypeHelper.interpretTransactionType( PersistenceUnitTransactionType txnType = PersistenceUnitTransactionTypeHelper.interpretTransactionType(
configurationValues.get( JPA_TRANSACTION_TYPE ) configurationValues.get( JPA_TRANSACTION_TYPE )
); );
Expand All @@ -657,7 +648,6 @@ private void applyTransactionProperties(StandardServiceRegistryBuilder ssrBuilde
// is it more appropriate to have this be based on bootstrap entry point (EE vs SE)? // is it more appropriate to have this be based on bootstrap entry point (EE vs SE)?
txnType = PersistenceUnitTransactionType.RESOURCE_LOCAL; txnType = PersistenceUnitTransactionType.RESOURCE_LOCAL;
} }
settings.setTransactionType( txnType );
boolean hasTxStrategy = configurationValues.containsKey( TRANSACTION_COORDINATOR_STRATEGY ); boolean hasTxStrategy = configurationValues.containsKey( TRANSACTION_COORDINATOR_STRATEGY );
if ( hasTxStrategy ) { if ( hasTxStrategy ) {
LOG.overridingTransactionStrategyDangerous( TRANSACTION_COORDINATOR_STRATEGY ); LOG.overridingTransactionStrategyDangerous( TRANSACTION_COORDINATOR_STRATEGY );
Expand Down

0 comments on commit 109410b

Please sign in to comment.