HHH-10942 - Session not flushing starting from 5.2.0 in Karaf + Aries JPA & JTA
This commit is contained in:
parent
d55ade52b2
commit
109410b153
|
@ -689,6 +689,14 @@ public interface SessionFactoryBuilder {
|
|||
|
||||
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.
|
||||
*
|
||||
|
|
|
@ -108,6 +108,7 @@ import static org.hibernate.cfg.AvailableSettings.USE_STRUCTURED_CACHE;
|
|||
import static org.hibernate.cfg.AvailableSettings.WRAP_RESULT_SETS;
|
||||
import static org.hibernate.cfg.AvailableSettings.ALLOW_UPDATE_OUTSIDE_TRANSACTION;
|
||||
import static org.hibernate.engine.config.spi.StandardConverters.BOOLEAN;
|
||||
import static org.hibernate.jpa.AvailableSettings.DISCARD_PC_ON_CLOSE;
|
||||
|
||||
/**
|
||||
* @author Gail Badner
|
||||
|
@ -471,6 +472,12 @@ public class SessionFactoryBuilderImpl implements SessionFactoryBuilderImplement
|
|||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SessionFactoryBuilder enableReleaseResourcesOnCloseEnabled(boolean enable) {
|
||||
this.options.releaseResourcesOnCloseEnabled = enable;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T extends SessionFactoryBuilder> T unwrap(Class<T> type) {
|
||||
|
@ -519,6 +526,7 @@ public class SessionFactoryBuilderImpl implements SessionFactoryBuilderImplement
|
|||
private boolean autoCloseSessionEnabled;
|
||||
private boolean jtaTransactionAccessEnabled;
|
||||
private boolean allowOutOfTransactionUpdateOperations;
|
||||
private boolean releaseResourcesOnCloseEnabled;
|
||||
|
||||
// (JTA) transaction handling
|
||||
private boolean jtaTrackByThread;
|
||||
|
@ -747,11 +755,18 @@ public class SessionFactoryBuilderImpl implements SessionFactoryBuilderImplement
|
|||
this.commentsEnabled = ConfigurationHelper.getBoolean( USE_SQL_COMMENTS, configurationSettings );
|
||||
|
||||
this.preferUserTransaction = ConfigurationHelper.getBoolean( PREFER_USER_TRANSACTION, configurationSettings, false );
|
||||
|
||||
this.allowOutOfTransactionUpdateOperations = ConfigurationHelper.getBoolean(
|
||||
ALLOW_UPDATE_OUTSIDE_TRANSACTION,
|
||||
configurationSettings,
|
||||
false
|
||||
);
|
||||
|
||||
this.releaseResourcesOnCloseEnabled = ConfigurationHelper.getBoolean(
|
||||
DISCARD_PC_ON_CLOSE,
|
||||
configurationSettings,
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
private static Interceptor determineInterceptor(Map configurationSettings, StrategySelector strategySelector) {
|
||||
|
@ -886,6 +901,11 @@ public class SessionFactoryBuilderImpl implements SessionFactoryBuilderImplement
|
|||
return allowOutOfTransactionUpdateOperations;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReleaseResourcesOnCloseEnabled() {
|
||||
return releaseResourcesOnCloseEnabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getBeanManagerReference() {
|
||||
return beanManagerReference;
|
||||
|
@ -1181,6 +1201,11 @@ public class SessionFactoryBuilderImpl implements SessionFactoryBuilderImplement
|
|||
return options.isAllowOutOfTransactionUpdateOperations();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReleaseResourcesOnCloseEnabled(){
|
||||
return options.releaseResourcesOnCloseEnabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getBeanManagerReference() {
|
||||
return options.getBeanManagerReference();
|
||||
|
|
|
@ -54,6 +54,7 @@ public class SessionFactoryOptionsImpl implements SessionFactoryOptions {
|
|||
private boolean jtaTransactionAccessEnabled;
|
||||
|
||||
private boolean allowOutOfTransactionUpdateOperations;
|
||||
private boolean releaseResourcesOnCloseEnabled;
|
||||
|
||||
// transaction handling
|
||||
private final boolean jtaTrackByThread;
|
||||
|
@ -371,6 +372,11 @@ public class SessionFactoryOptionsImpl implements SessionFactoryOptions {
|
|||
return allowOutOfTransactionUpdateOperations;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReleaseResourcesOnCloseEnabled() {
|
||||
return releaseResourcesOnCloseEnabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSecondLevelCacheEnabled() {
|
||||
return secondLevelCacheEnabled;
|
||||
|
|
|
@ -50,6 +50,8 @@ public interface SessionFactoryOptionsState {
|
|||
|
||||
boolean isAllowOutOfTransactionUpdateOperations();
|
||||
|
||||
boolean isReleaseResourcesOnCloseEnabled();
|
||||
|
||||
Object getBeanManagerReference();
|
||||
|
||||
Object getValidatorFactoryReference();
|
||||
|
|
|
@ -368,6 +368,12 @@ public abstract class AbstractDelegatingSessionFactoryBuilder<T extends Abstract
|
|||
return getThis();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SessionFactoryBuilder enableReleaseResourcesOnCloseEnabled(boolean enable) {
|
||||
delegate.enableReleaseResourcesOnCloseEnabled( enable );
|
||||
return getThis();
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <S extends SessionFactoryBuilder> S unwrap(Class<S> type) {
|
||||
|
|
|
@ -218,6 +218,11 @@ public class AbstractDelegatingSessionFactoryOptions implements SessionFactoryOp
|
|||
return delegate.isAllowOutOfTransactionUpdateOperations();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReleaseResourcesOnCloseEnabled() {
|
||||
return delegate.isReleaseResourcesOnCloseEnabled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSecondLevelCacheEnabled() {
|
||||
return delegate.isSecondLevelCacheEnabled();
|
||||
|
|
|
@ -203,4 +203,6 @@ public interface SessionFactoryOptions {
|
|||
boolean isProcedureParameterNullPassingEnabled();
|
||||
|
||||
boolean isAllowOutOfTransactionUpdateOperations();
|
||||
|
||||
boolean isReleaseResourcesOnCloseEnabled();
|
||||
}
|
||||
|
|
|
@ -114,7 +114,8 @@ public abstract class AbstractSharedSessionContract implements SharedSessionCont
|
|||
|
||||
private CacheMode cacheMode;
|
||||
|
||||
private boolean closed;
|
||||
protected boolean closed;
|
||||
protected boolean waitingForAutoClose;
|
||||
|
||||
// transient & non-final for Serialization purposes - ugh
|
||||
private transient SessionEventListenerManagerImpl sessionEventsManager = new SessionEventListenerManagerImpl();
|
||||
|
@ -306,6 +307,7 @@ public abstract class AbstractSharedSessionContract implements SharedSessionCont
|
|||
|
||||
protected void setClosed() {
|
||||
closed = true;
|
||||
waitingForAutoClose = false;
|
||||
cleanupOnClose();
|
||||
}
|
||||
|
||||
|
@ -342,6 +344,9 @@ public abstract class AbstractSharedSessionContract implements SharedSessionCont
|
|||
|
||||
@Override
|
||||
public boolean isTransactionInProgress() {
|
||||
if ( waitingForAutoClose ) {
|
||||
return transactionCoordinator.isTransactionActive();
|
||||
}
|
||||
return !isClosed() && transactionCoordinator.isTransactionActive();
|
||||
}
|
||||
|
||||
|
|
|
@ -242,6 +242,8 @@ public final class SessionImpl
|
|||
|
||||
private transient LoadEvent loadEvent; //cached LoadEvent instance
|
||||
|
||||
private transient boolean discardOnClose;
|
||||
|
||||
public SessionImpl(SessionFactoryImpl factory, SessionCreationOptions options) {
|
||||
super( factory, options );
|
||||
|
||||
|
@ -254,6 +256,7 @@ public final class SessionImpl
|
|||
this.autoClear = options.shouldAutoClear();
|
||||
this.autoClose = options.shouldAutoClose();
|
||||
this.disallowOutOfTransactionUpdateOperations = !factory.getSessionFactoryOptions().isAllowOutOfTransactionUpdateOperations();
|
||||
this.discardOnClose = getFactory().getSessionFactoryOptions().isReleaseResourcesOnCloseEnabled();
|
||||
|
||||
if ( options instanceof SharedSessionCreationOptions && ( (SharedSessionCreationOptions) options ).isTransactionCoordinatorShared() ) {
|
||||
final SharedSessionCreationOptions sharedOptions = (SharedSessionCreationOptions) options;
|
||||
|
@ -302,6 +305,7 @@ public final class SessionImpl
|
|||
|
||||
private void applyEntityManagerSpecificProperties() {
|
||||
for ( String key : ENTITY_MANAGER_SPECIFIC_PROPERTIES ) {
|
||||
final Map<String, Object> properties = getFactory().getProperties();
|
||||
if ( getFactory().getProperties().containsKey( key ) ) {
|
||||
this.properties.put( key, getFactory().getProperties().get( key ) );
|
||||
}
|
||||
|
@ -398,28 +402,26 @@ public final class SessionImpl
|
|||
|
||||
// todo : we want this check if usage is JPA, but not native Hibernate usage
|
||||
if ( getSessionFactory().getSessionFactoryOptions().isJpaBootstrap() ) {
|
||||
// Original hibernate-entitymanager EM#close behavior
|
||||
checkSessionFactoryOpen();
|
||||
checkOpen();
|
||||
if ( discardOnClose || !isTransactionInProgress() ) {
|
||||
super.close();
|
||||
}
|
||||
else {
|
||||
//Otherwise, session auto-close will be enabled by shouldAutoCloseSession().
|
||||
waitingForAutoClose = true;
|
||||
closed = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
super.close();
|
||||
|
||||
if ( getFactory().getStatistics().isStatisticsEnabled() ) {
|
||||
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
|
||||
|
@ -446,7 +448,7 @@ public final class SessionImpl
|
|||
checkSessionFactoryOpen();
|
||||
checkTransactionSynchStatus();
|
||||
try {
|
||||
return !isClosed();
|
||||
return !isClosed() && !waitingForAutoClose ;
|
||||
}
|
||||
catch (HibernateException he) {
|
||||
throw exceptionConverter.convert( he );
|
||||
|
@ -465,17 +467,20 @@ public final class SessionImpl
|
|||
}
|
||||
|
||||
private void managedFlush() {
|
||||
if ( isClosed() ) {
|
||||
if ( isClosed() && !waitingForAutoClose ) {
|
||||
log.trace( "Skipping auto-flush due to session closed" );
|
||||
return;
|
||||
}
|
||||
log.trace( "Automatically flushing session" );
|
||||
flush();
|
||||
doFlush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldAutoClose() {
|
||||
if ( isClosed() ) {
|
||||
if ( waitingForAutoClose ) {
|
||||
return true;
|
||||
}
|
||||
else if ( isClosed() ) {
|
||||
return false;
|
||||
}
|
||||
else if ( sessionOwner != null ) {
|
||||
|
@ -1383,10 +1388,13 @@ public final class SessionImpl
|
|||
@Override
|
||||
public void flush() throws HibernateException {
|
||||
checkOpen();
|
||||
doFlush();
|
||||
}
|
||||
|
||||
private void doFlush() {
|
||||
checkTransactionNeeded();
|
||||
checkTransactionSynchStatus();
|
||||
|
||||
|
||||
try {
|
||||
if ( persistenceContext.getCascadeLevel() > 0 ) {
|
||||
throw new HibernateException( "Flush during cascade is dangerous" );
|
||||
|
@ -2224,14 +2232,18 @@ public final class SessionImpl
|
|||
|
||||
@Override
|
||||
public ActionQueue getActionQueue() {
|
||||
if ( !waitingForAutoClose ) {
|
||||
checkOpen();
|
||||
}
|
||||
// checkTransactionSynchStatus();
|
||||
return actionQueue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PersistenceContext getPersistenceContext() {
|
||||
if ( !waitingForAutoClose ) {
|
||||
checkOpen();
|
||||
}
|
||||
// checkTransactionSynchStatus();
|
||||
return persistenceContext;
|
||||
}
|
||||
|
@ -3148,8 +3160,7 @@ public final class SessionImpl
|
|||
|
||||
@Override
|
||||
public void flushBeforeTransactionCompletion() {
|
||||
final boolean doFlush = ! isClosed()
|
||||
&& isTransactionFlushable()
|
||||
final boolean doFlush = isTransactionFlushable()
|
||||
&& getHibernateFlushMode() != FlushMode.MANUAL;
|
||||
|
||||
try {
|
||||
|
|
|
@ -145,7 +145,6 @@ public class EntityManagerFactoryBuilderImpl implements EntityManagerFactoryBuil
|
|||
private final StandardServiceRegistry standardServiceRegistry;
|
||||
private final ManagedResources managedResources;
|
||||
private final MetadataBuilderImplementor metamodelBuilder;
|
||||
private final SettingsImpl settings;
|
||||
|
||||
private static class JpaEntityNotFoundDelegate implements EntityNotFoundDelegate, Serializable {
|
||||
/**
|
||||
|
@ -200,7 +199,7 @@ public class EntityManagerFactoryBuilderImpl implements EntityManagerFactoryBuil
|
|||
|
||||
// Build the "standard" service registry
|
||||
ssrBuilder.applySettings( configurationValues );
|
||||
this.settings = configure( ssrBuilder );
|
||||
configure( ssrBuilder );
|
||||
this.standardServiceRegistry = ssrBuilder.build();
|
||||
configure( standardServiceRegistry, mergedSettings );
|
||||
|
||||
|
@ -580,11 +579,10 @@ public class EntityManagerFactoryBuilderImpl implements EntityManagerFactoryBuil
|
|||
return new CacheRegionDefinition( cacheType, role, usage, region, lazyProperty );
|
||||
}
|
||||
|
||||
private SettingsImpl configure(StandardServiceRegistryBuilder ssrBuilder) {
|
||||
final SettingsImpl settings = new SettingsImpl();
|
||||
private void configure(StandardServiceRegistryBuilder ssrBuilder) {
|
||||
|
||||
applyJdbcConnectionProperties( ssrBuilder );
|
||||
applyTransactionProperties( ssrBuilder, settings );
|
||||
applyTransactionProperties( ssrBuilder );
|
||||
|
||||
// flush beforeQuery completion validation
|
||||
if ( "true".equals( configurationValues.get( Environment.FLUSH_BEFORE_COMPLETION ) ) ) {
|
||||
|
@ -592,11 +590,6 @@ public class EntityManagerFactoryBuilderImpl implements EntityManagerFactoryBuil
|
|||
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 Object interceptorSetting = configurationValues.remove( AvailableSettings.SESSION_INTERCEPTOR );
|
||||
// if ( interceptorSetting != null ) {
|
||||
|
@ -604,8 +597,6 @@ public class EntityManagerFactoryBuilderImpl implements EntityManagerFactoryBuil
|
|||
// loadSessionInterceptorClass( interceptorSetting, strategySelector )
|
||||
// );
|
||||
// }
|
||||
|
||||
return settings;
|
||||
}
|
||||
|
||||
private void applyJdbcConnectionProperties(StandardServiceRegistryBuilder ssrBuilder) {
|
||||
|
@ -646,7 +637,7 @@ public class EntityManagerFactoryBuilderImpl implements EntityManagerFactoryBuil
|
|||
}
|
||||
}
|
||||
|
||||
private void applyTransactionProperties(StandardServiceRegistryBuilder ssrBuilder, SettingsImpl settings) {
|
||||
private void applyTransactionProperties(StandardServiceRegistryBuilder ssrBuilder) {
|
||||
PersistenceUnitTransactionType txnType = PersistenceUnitTransactionTypeHelper.interpretTransactionType(
|
||||
configurationValues.get( JPA_TRANSACTION_TYPE )
|
||||
);
|
||||
|
@ -657,7 +648,6 @@ public class EntityManagerFactoryBuilderImpl implements EntityManagerFactoryBuil
|
|||
// is it more appropriate to have this be based on bootstrap entry point (EE vs SE)?
|
||||
txnType = PersistenceUnitTransactionType.RESOURCE_LOCAL;
|
||||
}
|
||||
settings.setTransactionType( txnType );
|
||||
boolean hasTxStrategy = configurationValues.containsKey( TRANSACTION_COORDINATOR_STRATEGY );
|
||||
if ( hasTxStrategy ) {
|
||||
LOG.overridingTransactionStrategyDangerous( TRANSACTION_COORDINATOR_STRATEGY );
|
||||
|
|
|
@ -1,51 +0,0 @@
|
|||
/*
|
||||
* 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.jpa.boot.internal;
|
||||
|
||||
import javax.persistence.spi.PersistenceUnitTransactionType;
|
||||
|
||||
import org.hibernate.Interceptor;
|
||||
import org.hibernate.jpa.boot.spi.Settings;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class SettingsImpl implements Settings {
|
||||
private PersistenceUnitTransactionType transactionType;
|
||||
private boolean releaseResourcesOnCloseEnabled;
|
||||
private Class<? extends Interceptor> sessionInterceptorClass;
|
||||
|
||||
@Override
|
||||
public PersistenceUnitTransactionType getTransactionType() {
|
||||
return transactionType;
|
||||
}
|
||||
|
||||
public SettingsImpl setTransactionType(PersistenceUnitTransactionType transactionType) {
|
||||
this.transactionType = transactionType;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReleaseResourcesOnCloseEnabled() {
|
||||
return releaseResourcesOnCloseEnabled;
|
||||
}
|
||||
|
||||
public SettingsImpl setReleaseResourcesOnCloseEnabled(boolean releaseResourcesOnCloseEnabled) {
|
||||
this.releaseResourcesOnCloseEnabled = releaseResourcesOnCloseEnabled;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends Interceptor> getSessionInterceptorClass() {
|
||||
return sessionInterceptorClass;
|
||||
}
|
||||
|
||||
public SettingsImpl setSessionInterceptorClass(Class<? extends Interceptor> sessionInterceptorClass) {
|
||||
this.sessionInterceptorClass = sessionInterceptorClass;
|
||||
return this;
|
||||
}
|
||||
}
|
|
@ -1,30 +0,0 @@
|
|||
/*
|
||||
* 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.jpa.boot.spi;
|
||||
|
||||
import javax.persistence.spi.PersistenceUnitTransactionType;
|
||||
|
||||
import org.hibernate.Interceptor;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface Settings {
|
||||
public PersistenceUnitTransactionType getTransactionType();
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* @return {@code true}/{@code false}
|
||||
*/
|
||||
public boolean isReleaseResourcesOnCloseEnabled();
|
||||
|
||||
public Class<? extends Interceptor> getSessionInterceptorClass();
|
||||
|
||||
}
|
Loading…
Reference in New Issue