HibernateJpaVendorAdapter and LocalSessionFactoryBuilder enforce Hibernate 5.2's connection handling mode DELAYED_ACQUISITION_AND_HOLD
Issue: SPR-14393
This commit is contained in:
parent
5e08598a2a
commit
711eb99812
|
@ -235,7 +235,6 @@ public class HibernateTransactionManager extends AbstractPlatformTransactionMana
|
|||
* <p>Default is "false". Turning this flag on enforces over-commit holdability on the
|
||||
* underlying JDBC Connection (if {@link #prepareConnection "prepareConnection"} is on)
|
||||
* and skips the disconnect-on-completion step.
|
||||
* @since 4.2
|
||||
* @see Connection#setHoldability
|
||||
* @see ResultSet#HOLD_CURSORS_OVER_COMMIT
|
||||
* @see #disconnectOnCompletion(Session)
|
||||
|
@ -689,7 +688,6 @@ public class HibernateTransactionManager extends AbstractPlatformTransactionMana
|
|||
* <p>The default implementation simply calls {@link Session#disconnect()}.
|
||||
* Subclasses may override this with a no-op or with fine-tuned disconnection logic.
|
||||
* @param session the Hibernate Session to disconnect
|
||||
* @since 4.2
|
||||
* @see Session#disconnect()
|
||||
*/
|
||||
protected void disconnectOnCompletion(Session session) {
|
||||
|
|
|
@ -139,6 +139,10 @@ public class LocalSessionFactoryBuilder extends Configuration {
|
|||
if (dataSource != null) {
|
||||
getProperties().put(Environment.DATASOURCE, dataSource);
|
||||
}
|
||||
|
||||
// Hibernate 5.2: manually enforce connection release mode ON_CLOSE (the former default)
|
||||
getProperties().put("hibernate.connection.handling_mode", "DELAYED_ACQUISITION_AND_HOLD");
|
||||
|
||||
getProperties().put(AvailableSettings.CLASSLOADERS, Collections.singleton(resourceLoader.getClassLoader()));
|
||||
this.resourcePatternResolver = ResourcePatternUtils.getResourcePatternResolver(resourceLoader);
|
||||
}
|
||||
|
@ -157,6 +161,7 @@ public class LocalSessionFactoryBuilder extends Configuration {
|
|||
*/
|
||||
public LocalSessionFactoryBuilder setJtaTransactionManager(Object jtaTransactionManager) {
|
||||
Assert.notNull(jtaTransactionManager, "Transaction manager reference must not be null");
|
||||
|
||||
if (jtaTransactionManager instanceof JtaTransactionManager) {
|
||||
boolean webspherePresent = ClassUtils.isPresent("com.ibm.wsspi.uow.UOWManager", getClass().getClassLoader());
|
||||
if (webspherePresent) {
|
||||
|
@ -182,6 +187,10 @@ public class LocalSessionFactoryBuilder extends Configuration {
|
|||
throw new IllegalArgumentException(
|
||||
"Unknown transaction manager type: " + jtaTransactionManager.getClass().getName());
|
||||
}
|
||||
|
||||
// Hibernate 5.2: manually enforce connection release mode AFTER_STATEMENT (the JTA default)
|
||||
getProperties().remove("hibernate.connection.handling_mode", "DELAYED_ACQUISITION_AND_RELEASE_AFTER_STATEMENT");
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
|
@ -126,7 +126,7 @@ public class HibernateJpaDialect extends DefaultJpaDialect {
|
|||
}
|
||||
|
||||
|
||||
private boolean prepareConnection = (HibernateConnectionHandle.sessionConnectionMethod == null);
|
||||
boolean prepareConnection = (HibernateConnectionHandle.sessionConnectionMethod == null);
|
||||
|
||||
|
||||
/**
|
||||
|
@ -362,25 +362,15 @@ public class HibernateJpaDialect extends DefaultJpaDialect {
|
|||
}
|
||||
if (this.preparedCon != null && this.session.isConnected()) {
|
||||
Connection conToReset = HibernateConnectionHandle.doGetConnection(this.session);
|
||||
if (!isEquivalentConnection(conToReset)) {
|
||||
if (conToReset != this.preparedCon) {
|
||||
LogFactory.getLog(HibernateJpaDialect.class).warn(
|
||||
"JDBC Connection to reset not equivalent to originally prepared Connection - please " +
|
||||
"JDBC Connection to reset not identical to originally prepared Connection - please " +
|
||||
"make sure to use connection release mode ON_CLOSE (the default) and to run against " +
|
||||
"Hibernate 4.2+ (or switch HibernateJpaDialect's prepareConnection flag to false");
|
||||
}
|
||||
DataSourceUtils.resetConnectionAfterTransaction(conToReset, this.previousIsolationLevel);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isEquivalentConnection(Connection con) {
|
||||
try {
|
||||
return (con.equals(this.preparedCon) ||
|
||||
con.unwrap(Connection.class).equals(this.preparedCon.unwrap(Connection.class)));
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -101,6 +101,27 @@ public class HibernateJpaVendorAdapter extends AbstractJpaVendorAdapter {
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set whether to prepare the underlying JDBC Connection of a transactional
|
||||
* Hibernate Session, that is, whether to apply a transaction-specific
|
||||
* isolation level and/or the transaction's read-only flag to the underlying
|
||||
* JDBC Connection.
|
||||
* <p>See {@link HibernateJpaDialect#setPrepareConnection(boolean)} for details.
|
||||
* This is just a convenience flag passed through to {@code HibernateJpaDialect}.
|
||||
* <p>On Hibernate 5.2, this flag remains {@code true} by default like against
|
||||
* previous Hibernate versions. The vendor adapter manually enforces Hibernate's
|
||||
* new connection handling mode {@code DELAYED_ACQUISITION_AND_HOLD} in that case
|
||||
* unless a user-specified connection handling mode property indicates otherwise;
|
||||
* switch this flag to {@code false} to avoid that interference.
|
||||
* @since 4.3.1
|
||||
* @see #getJpaPropertyMap()
|
||||
* @see HibernateJpaDialect#beginTransaction
|
||||
*/
|
||||
public void setPrepareConnection(boolean prepareConnection) {
|
||||
this.jpaDialect.setPrepareConnection(prepareConnection);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public PersistenceProvider getPersistenceProvider() {
|
||||
return this.persistenceProvider;
|
||||
|
@ -132,6 +153,11 @@ public class HibernateJpaVendorAdapter extends AbstractJpaVendorAdapter {
|
|||
jpaProperties.put(Environment.SHOW_SQL, "true");
|
||||
}
|
||||
|
||||
if (this.jpaDialect.prepareConnection) {
|
||||
// Hibernate 5.2: manually enforce connection release mode ON_CLOSE (the former default)
|
||||
jpaProperties.put("hibernate.connection.handling_mode", "DELAYED_ACQUISITION_AND_HOLD");
|
||||
}
|
||||
|
||||
return jpaProperties;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue