diff --git a/spring-orm/src/main/java/org/springframework/orm/hibernate5/HibernateTransactionManager.java b/spring-orm/src/main/java/org/springframework/orm/hibernate5/HibernateTransactionManager.java index 8bf3241ce3c..65990f3e833 100644 --- a/spring-orm/src/main/java/org/springframework/orm/hibernate5/HibernateTransactionManager.java +++ b/spring-orm/src/main/java/org/springframework/orm/hibernate5/HibernateTransactionManager.java @@ -458,7 +458,6 @@ public class HibernateTransactionManager extends AbstractPlatformTransactionMana } @Override - @SuppressWarnings("deprecation") protected void doBegin(Object transaction, TransactionDefinition definition) { HibernateTransactionObject txObject = (HibernateTransactionObject) transaction; @@ -470,7 +469,7 @@ public class HibernateTransactionManager extends AbstractPlatformTransactionMana "on a single DataSource, no matter whether Hibernate or JDBC access."); } - Session session = null; + SessionImplementor session = null; try { if (!txObject.hasSessionHolder() || txObject.getSessionHolder().isSynchronizedWithTransaction()) { @@ -487,17 +486,18 @@ public class HibernateTransactionManager extends AbstractPlatformTransactionMana txObject.setSession(newSession); } - session = txObject.getSessionHolder().getSession(); + session = txObject.getSessionHolder().getSession().unwrap(SessionImplementor.class); boolean holdabilityNeeded = this.allowResultAccessAfterCompletion && !txObject.isNewSession(); boolean isolationLevelNeeded = (definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT); if (holdabilityNeeded || isolationLevelNeeded || definition.isReadOnly()) { - if (this.prepareConnection && isSameConnectionForEntireSession(session)) { + if (this.prepareConnection && ConnectionReleaseMode.ON_CLOSE.equals( + session.getJdbcCoordinator().getLogicalConnection().getConnectionHandlingMode().getReleaseMode())) { // We're allowed to change the transaction settings of the JDBC Connection. if (logger.isDebugEnabled()) { logger.debug("Preparing JDBC Connection of Hibernate Session [" + session + "]"); } - Connection con = ((SessionImplementor) session).connection(); + Connection con = session.connection(); Integer previousIsolationLevel = DataSourceUtils.prepareConnectionForTransaction(con, definition); txObject.setPreviousIsolationLevel(previousIsolationLevel); txObject.setReadOnly(definition.isReadOnly()); @@ -508,6 +508,7 @@ public class HibernateTransactionManager extends AbstractPlatformTransactionMana con.setHoldability(ResultSet.HOLD_CURSORS_OVER_COMMIT); } } + txObject.connectionPrepared(); } else { // Not allowed to change the transaction settings of the JDBC Connection. @@ -516,7 +517,7 @@ public class HibernateTransactionManager extends AbstractPlatformTransactionMana throw new InvalidIsolationLevelException( "HibernateTransactionManager is not allowed to support custom isolation levels: " + "make sure that its 'prepareConnection' flag is on (the default) and that the " + - "Hibernate connection release mode is set to 'on_close' (the default for JDBC)."); + "Hibernate connection release mode is set to ON_CLOSE."); } if (logger.isDebugEnabled()) { logger.debug("Not preparing JDBC Connection of Hibernate Session [" + session + "]"); @@ -526,7 +527,7 @@ public class HibernateTransactionManager extends AbstractPlatformTransactionMana if (definition.isReadOnly() && txObject.isNewSession()) { // Just set to MANUAL in case of a new Session for this transaction. - session.setFlushMode(FlushMode.MANUAL); + session.setHibernateFlushMode(FlushMode.MANUAL); // As of 5.1, we're also setting Hibernate's read-only entity mode by default. session.setDefaultReadOnly(true); } @@ -535,7 +536,7 @@ public class HibernateTransactionManager extends AbstractPlatformTransactionMana // We need AUTO or COMMIT for a non-read-only transaction. FlushMode flushMode = session.getHibernateFlushMode(); if (FlushMode.MANUAL.equals(flushMode)) { - session.setFlushMode(FlushMode.AUTO); + session.setHibernateFlushMode(FlushMode.AUTO); txObject.getSessionHolder().setPreviousFlushMode(flushMode); } } @@ -561,8 +562,7 @@ public class HibernateTransactionManager extends AbstractPlatformTransactionMana // Register the Hibernate Session's JDBC Connection for the DataSource, if set. if (getDataSource() != null) { - SessionImplementor sessionImpl = (SessionImplementor) session; - ConnectionHolder conHolder = new ConnectionHolder(sessionImpl::connection); + ConnectionHolder conHolder = new ConnectionHolder(session::connection); if (timeout != TransactionDefinition.TIMEOUT_DEFAULT) { conHolder.setTimeoutInSeconds(timeout); } @@ -704,7 +704,6 @@ public class HibernateTransactionManager extends AbstractPlatformTransactionMana } @Override - @SuppressWarnings("deprecation") protected void doCleanupAfterCompletion(Object transaction) { HibernateTransactionObject txObject = (HibernateTransactionObject) transaction; @@ -718,13 +717,14 @@ public class HibernateTransactionManager extends AbstractPlatformTransactionMana TransactionSynchronizationManager.unbindResource(getDataSource()); } - Session session = txObject.getSessionHolder().getSession(); - if (this.prepareConnection && isPhysicallyConnected(session)) { - // We're running with connection release mode "on_close": We're able to reset + SessionImplementor session = txObject.getSessionHolder().getSession().unwrap(SessionImplementor.class); + if (txObject.needsConnectionReset() && + session.getJdbcCoordinator().getLogicalConnection().isPhysicallyConnected()) { + // We're running with connection release mode ON_CLOSE: We're able to reset // the isolation level and/or read-only flag of the JDBC Connection here. // Else, we need to rely on the connection pool to perform proper cleanup. try { - Connection con = ((SessionImplementor) session).connection(); + Connection con = session.connection(); Integer previousHoldability = txObject.getPreviousHoldability(); if (previousHoldability != null) { con.setHoldability(previousHoldability); @@ -751,7 +751,7 @@ public class HibernateTransactionManager extends AbstractPlatformTransactionMana logger.debug("Not closing pre-bound Hibernate Session [" + session + "] after transaction"); } if (txObject.getSessionHolder().getPreviousFlushMode() != null) { - session.setFlushMode(txObject.getSessionHolder().getPreviousFlushMode()); + session.setHibernateFlushMode(txObject.getSessionHolder().getPreviousFlushMode()); } if (!this.allowResultAccessAfterCompletion && !this.hibernateManagedSession) { disconnectOnCompletion(session); @@ -772,41 +772,6 @@ public class HibernateTransactionManager extends AbstractPlatformTransactionMana session.disconnect(); } - /** - * Return whether the given Hibernate Session will always hold the same - * JDBC Connection. This is used to check whether the transaction manager - * can safely prepare and clean up the JDBC Connection used for a transaction. - *
The default implementation checks the Session's connection release mode - * to be "on_close". - * @param session the Hibernate Session to check - * @see ConnectionReleaseMode#ON_CLOSE - */ - @SuppressWarnings("deprecation") - protected boolean isSameConnectionForEntireSession(Session session) { - if (!(session instanceof SessionImplementor)) { - // The best we can do is to assume we're safe. - return true; - } - ConnectionReleaseMode releaseMode = - ((SessionImplementor) session).getJdbcCoordinator().getConnectionReleaseMode(); - return ConnectionReleaseMode.ON_CLOSE.equals(releaseMode); - } - - /** - * Determine whether the given Session is (still) physically connected - * to the database, that is, holds an active JDBC Connection internally. - * @param session the Hibernate Session to check - * @see #isSameConnectionForEntireSession(Session) - */ - protected boolean isPhysicallyConnected(Session session) { - if (!(session instanceof SessionImplementor)) { - // The best we can do is to check whether we're logically connected. - return session.isConnected(); - } - return ((SessionImplementor) session).getJdbcCoordinator().getLogicalConnection().isPhysicallyConnected(); - } - - /** * Convert the given HibernateException to an appropriate exception * from the {@code org.springframework.dao} hierarchy. @@ -834,6 +799,8 @@ public class HibernateTransactionManager extends AbstractPlatformTransactionMana private boolean newSession; + private boolean needsConnectionReset; + @Nullable private Integer previousHoldability; @@ -872,6 +839,14 @@ public class HibernateTransactionManager extends AbstractPlatformTransactionMana return this.newSession; } + public void connectionPrepared() { + this.needsConnectionReset = true; + } + + public boolean needsConnectionReset() { + return this.needsConnectionReset; + } + public void setPreviousHoldability(@Nullable Integer previousHoldability) { this.previousHoldability = previousHoldability; } diff --git a/spring-orm/src/main/java/org/springframework/orm/hibernate5/SpringJtaSessionContext.java b/spring-orm/src/main/java/org/springframework/orm/hibernate5/SpringJtaSessionContext.java index 273e362c5db..2c6d19bc78f 100644 --- a/spring-orm/src/main/java/org/springframework/orm/hibernate5/SpringJtaSessionContext.java +++ b/spring-orm/src/main/java/org/springframework/orm/hibernate5/SpringJtaSessionContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2020 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -38,11 +38,10 @@ public class SpringJtaSessionContext extends JTASessionContext { } @Override - @SuppressWarnings("deprecation") protected Session buildOrObtainSession() { Session session = super.buildOrObtainSession(); if (TransactionSynchronizationManager.isCurrentTransactionReadOnly()) { - session.setFlushMode(FlushMode.MANUAL); + session.setHibernateFlushMode(FlushMode.MANUAL); } return session; } diff --git a/spring-orm/src/main/java/org/springframework/orm/hibernate5/SpringSessionContext.java b/spring-orm/src/main/java/org/springframework/orm/hibernate5/SpringSessionContext.java index 1704b04957c..859abaf7284 100644 --- a/spring-orm/src/main/java/org/springframework/orm/hibernate5/SpringSessionContext.java +++ b/spring-orm/src/main/java/org/springframework/orm/hibernate5/SpringSessionContext.java @@ -80,7 +80,6 @@ public class SpringSessionContext implements CurrentSessionContext { * Retrieve the Spring-managed Session for the current thread, if any. */ @Override - @SuppressWarnings("deprecation") public Session currentSession() throws HibernateException { Object value = TransactionSynchronizationManager.getResource(this.sessionFactory); if (value instanceof Session) { @@ -100,7 +99,7 @@ public class SpringSessionContext implements CurrentSessionContext { FlushMode flushMode = session.getHibernateFlushMode(); if (flushMode.equals(FlushMode.MANUAL) && !TransactionSynchronizationManager.isCurrentTransactionReadOnly()) { - session.setFlushMode(FlushMode.AUTO); + session.setHibernateFlushMode(FlushMode.AUTO); sessionHolder.setPreviousFlushMode(flushMode); } } @@ -130,7 +129,7 @@ public class SpringSessionContext implements CurrentSessionContext { if (TransactionSynchronizationManager.isSynchronizationActive()) { Session session = this.sessionFactory.openSession(); if (TransactionSynchronizationManager.isCurrentTransactionReadOnly()) { - session.setFlushMode(FlushMode.MANUAL); + session.setHibernateFlushMode(FlushMode.MANUAL); } SessionHolder sessionHolder = new SessionHolder(session); TransactionSynchronizationManager.registerSynchronization( diff --git a/spring-orm/src/main/java/org/springframework/orm/hibernate5/SpringSessionSynchronization.java b/spring-orm/src/main/java/org/springframework/orm/hibernate5/SpringSessionSynchronization.java index 374110f39c9..896a7986554 100644 --- a/spring-orm/src/main/java/org/springframework/orm/hibernate5/SpringSessionSynchronization.java +++ b/spring-orm/src/main/java/org/springframework/orm/hibernate5/SpringSessionSynchronization.java @@ -98,13 +98,12 @@ public class SpringSessionSynchronization implements TransactionSynchronization, } @Override - @SuppressWarnings("deprecation") public void beforeCompletion() { try { Session session = this.sessionHolder.getSession(); if (this.sessionHolder.getPreviousFlushMode() != null) { // In case of pre-bound Session, restore previous flush mode. - session.setFlushMode(this.sessionHolder.getPreviousFlushMode()); + session.setHibernateFlushMode(this.sessionHolder.getPreviousFlushMode()); } // Eagerly disconnect the Session here, to make release mode "on_close" work nicely. session.disconnect(); diff --git a/spring-orm/src/main/java/org/springframework/orm/hibernate5/support/OpenSessionInViewFilter.java b/spring-orm/src/main/java/org/springframework/orm/hibernate5/support/OpenSessionInViewFilter.java index ec23f51c025..3379e517c38 100644 --- a/spring-orm/src/main/java/org/springframework/orm/hibernate5/support/OpenSessionInViewFilter.java +++ b/spring-orm/src/main/java/org/springframework/orm/hibernate5/support/OpenSessionInViewFilter.java @@ -204,11 +204,10 @@ public class OpenSessionInViewFilter extends OncePerRequestFilter { * @throws DataAccessResourceFailureException if the Session could not be created * @see FlushMode#MANUAL */ - @SuppressWarnings("deprecation") protected Session openSession(SessionFactory sessionFactory) throws DataAccessResourceFailureException { try { Session session = sessionFactory.openSession(); - session.setFlushMode(FlushMode.MANUAL); + session.setHibernateFlushMode(FlushMode.MANUAL); return session; } catch (HibernateException ex) { diff --git a/spring-orm/src/main/java/org/springframework/orm/hibernate5/support/OpenSessionInViewInterceptor.java b/spring-orm/src/main/java/org/springframework/orm/hibernate5/support/OpenSessionInViewInterceptor.java index ac131bab44a..1bece003c2f 100644 --- a/spring-orm/src/main/java/org/springframework/orm/hibernate5/support/OpenSessionInViewInterceptor.java +++ b/spring-orm/src/main/java/org/springframework/orm/hibernate5/support/OpenSessionInViewInterceptor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2020 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -186,11 +186,10 @@ public class OpenSessionInViewInterceptor implements AsyncWebRequestInterceptor * @throws DataAccessResourceFailureException if the Session could not be created * @see FlushMode#MANUAL */ - @SuppressWarnings("deprecation") protected Session openSession() throws DataAccessResourceFailureException { try { Session session = obtainSessionFactory().openSession(); - session.setFlushMode(FlushMode.MANUAL); + session.setHibernateFlushMode(FlushMode.MANUAL); return session; } catch (HibernateException ex) { diff --git a/spring-orm/src/main/java/org/springframework/orm/hibernate5/support/OpenSessionInterceptor.java b/spring-orm/src/main/java/org/springframework/orm/hibernate5/support/OpenSessionInterceptor.java index 30e6f842b67..26a3a70af94 100644 --- a/spring-orm/src/main/java/org/springframework/orm/hibernate5/support/OpenSessionInterceptor.java +++ b/spring-orm/src/main/java/org/springframework/orm/hibernate5/support/OpenSessionInterceptor.java @@ -111,13 +111,12 @@ public class OpenSessionInterceptor implements MethodInterceptor, InitializingBe * @since 5.0 * @see FlushMode#MANUAL */ - @SuppressWarnings("deprecation") protected Session openSession(SessionFactory sessionFactory) throws DataAccessResourceFailureException { Session session = openSession(); if (session == null) { try { session = sessionFactory.openSession(); - session.setFlushMode(FlushMode.MANUAL); + session.setHibernateFlushMode(FlushMode.MANUAL); } catch (HibernateException ex) { throw new DataAccessResourceFailureException("Could not open Hibernate Session", ex); diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/HibernateJpaDialect.java b/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/HibernateJpaDialect.java index 06106935b7d..a6d82beb63c 100644 --- a/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/HibernateJpaDialect.java +++ b/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/HibernateJpaDialect.java @@ -16,14 +16,13 @@ package org.springframework.orm.jpa.vendor; -import java.lang.reflect.Method; import java.sql.Connection; import java.sql.SQLException; import javax.persistence.EntityManager; import javax.persistence.PersistenceException; -import org.apache.commons.logging.LogFactory; +import org.hibernate.ConnectionReleaseMode; import org.hibernate.FlushMode; import org.hibernate.HibernateException; import org.hibernate.JDBCException; @@ -43,6 +42,7 @@ import org.hibernate.UnresolvableObjectException; import org.hibernate.WrongClassException; import org.hibernate.dialect.lock.OptimisticEntityLockException; import org.hibernate.dialect.lock.PessimisticEntityLockException; +import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.exception.ConstraintViolationException; import org.hibernate.exception.DataException; import org.hibernate.exception.JDBCConnectionException; @@ -71,12 +71,10 @@ import org.springframework.transaction.InvalidIsolationLevelException; import org.springframework.transaction.TransactionDefinition; import org.springframework.transaction.TransactionException; import org.springframework.transaction.support.ResourceTransactionDefinition; -import org.springframework.util.Assert; -import org.springframework.util.ReflectionUtils; /** * {@link org.springframework.orm.jpa.JpaDialect} implementation for - * Hibernate EntityManager. Developed against Hibernate 5.1/5.2/5.3/5.4. + * Hibernate EntityManager. Developed against Hibernate 5.2/5.3/5.4. * * @author Juergen Hoeller * @author Costin Leau @@ -88,27 +86,6 @@ import org.springframework.util.ReflectionUtils; @SuppressWarnings("serial") public class HibernateJpaDialect extends DefaultJpaDialect { - private static Method getFlushMode; - - static { - try { - // Hibernate 5.2+ getHibernateFlushMode() - getFlushMode = Session.class.getMethod("getHibernateFlushMode"); - } - catch (NoSuchMethodException ex) { - try { - // Classic Hibernate getFlushMode() with FlushMode return type - getFlushMode = Session.class.getMethod("getFlushMode"); - } - catch (NoSuchMethodException ex2) { - throw new IllegalStateException("No compatible Hibernate getFlushMode signature found", ex2); - } - } - // Check that it is the Hibernate FlushMode type, not JPA's... - Assert.state(FlushMode.class == getFlushMode.getReturnType(), "Could not find Hibernate getFlushMode method"); - } - - boolean prepareConnection = true; @Nullable @@ -159,7 +136,7 @@ public class HibernateJpaDialect extends DefaultJpaDialect { public Object beginTransaction(EntityManager entityManager, TransactionDefinition definition) throws PersistenceException, SQLException, TransactionException { - Session session = getSession(entityManager); + SessionImplementor session = getSession(entityManager); if (definition.getTimeout() != TransactionDefinition.TIMEOUT_DEFAULT) { session.getTransaction().setTimeout(definition.getTimeout()); @@ -170,13 +147,16 @@ public class HibernateJpaDialect extends DefaultJpaDialect { Connection preparedCon = null; if (isolationLevelNeeded || definition.isReadOnly()) { - if (this.prepareConnection) { - preparedCon = HibernateConnectionHandle.doGetConnection(session); + if (this.prepareConnection && ConnectionReleaseMode.ON_CLOSE.equals( + session.getJdbcCoordinator().getLogicalConnection().getConnectionHandlingMode().getReleaseMode())) { + preparedCon = session.connection(); previousIsolationLevel = DataSourceUtils.prepareConnectionForTransaction(preparedCon, definition); } else if (isolationLevelNeeded) { - throw new InvalidIsolationLevelException(getClass().getSimpleName() + - " does not support custom isolation levels since the 'prepareConnection' flag is off."); + throw new InvalidIsolationLevelException( + "HibernateJpaDialect is not allowed to support custom isolation levels: " + + "make sure that its 'prepareConnection' flag is on (the default) and that the " + + "Hibernate connection release mode is set to ON_CLOSE."); } } @@ -195,34 +175,32 @@ public class HibernateJpaDialect extends DefaultJpaDialect { } } return new SessionTransactionData( - session, previousFlushMode, preparedCon, previousIsolationLevel, definition.isReadOnly()); + session, previousFlushMode, (preparedCon != null), previousIsolationLevel, definition.isReadOnly()); } @Override public Object prepareTransaction(EntityManager entityManager, boolean readOnly, @Nullable String name) throws PersistenceException { - Session session = getSession(entityManager); + SessionImplementor session = getSession(entityManager); FlushMode previousFlushMode = prepareFlushMode(session, readOnly); - return new SessionTransactionData(session, previousFlushMode, null, null, readOnly); + return new SessionTransactionData(session, previousFlushMode, false, null, readOnly); } - @SuppressWarnings("deprecation") @Nullable protected FlushMode prepareFlushMode(Session session, boolean readOnly) throws PersistenceException { - FlushMode flushMode = (FlushMode) ReflectionUtils.invokeMethod(getFlushMode, session); - Assert.state(flushMode != null, "No FlushMode from Session"); + FlushMode flushMode = session.getHibernateFlushMode(); if (readOnly) { // We should suppress flushing for a read-only transaction. if (!flushMode.equals(FlushMode.MANUAL)) { - session.setFlushMode(FlushMode.MANUAL); + session.setHibernateFlushMode(FlushMode.MANUAL); return flushMode; } } else { // We need AUTO or COMMIT for a non-read-only transaction. if (flushMode.lessThan(FlushMode.COMMIT)) { - session.setFlushMode(FlushMode.AUTO); + session.setHibernateFlushMode(FlushMode.AUTO); return flushMode; } } @@ -241,7 +219,7 @@ public class HibernateJpaDialect extends DefaultJpaDialect { public ConnectionHandle getJdbcConnection(EntityManager entityManager, boolean readOnly) throws PersistenceException, SQLException { - Session session = getSession(entityManager); + SessionImplementor session = getSession(entityManager); return new HibernateConnectionHandle(session); } @@ -353,32 +331,31 @@ public class HibernateJpaDialect extends DefaultJpaDialect { return new JpaSystemException(ex); } - protected Session getSession(EntityManager entityManager) { - return entityManager.unwrap(Session.class); + protected SessionImplementor getSession(EntityManager entityManager) { + return entityManager.unwrap(SessionImplementor.class); } private static class SessionTransactionData { - private final Session session; + private final SessionImplementor session; @Nullable private final FlushMode previousFlushMode; - @Nullable - private final Connection preparedCon; + private final boolean needsConnectionReset; @Nullable private final Integer previousIsolationLevel; private final boolean readOnly; - public SessionTransactionData(Session session, @Nullable FlushMode previousFlushMode, - @Nullable Connection preparedCon, @Nullable Integer previousIsolationLevel, boolean readOnly) { + public SessionTransactionData(SessionImplementor session, @Nullable FlushMode previousFlushMode, + boolean connectionPrepared, @Nullable Integer previousIsolationLevel, boolean readOnly) { this.session = session; this.previousFlushMode = previousFlushMode; - this.preparedCon = preparedCon; + this.needsConnectionReset = connectionPrepared; this.previousIsolationLevel = previousIsolationLevel; this.readOnly = readOnly; } @@ -388,14 +365,9 @@ public class HibernateJpaDialect extends DefaultJpaDialect { if (this.previousFlushMode != null) { this.session.setFlushMode(this.previousFlushMode); } - if (this.preparedCon != null && this.session.isConnected()) { - Connection conToReset = HibernateConnectionHandle.doGetConnection(this.session); - if (conToReset != this.preparedCon) { - LogFactory.getLog(HibernateJpaDialect.class).warn( - "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"); - } + if (this.needsConnectionReset && + this.session.getJdbcCoordinator().getLogicalConnection().isPhysicallyConnected()) { + Connection conToReset = this.session.connection(); DataSourceUtils.resetConnectionAfterTransaction( conToReset, this.previousIsolationLevel, this.readOnly); } @@ -405,35 +377,15 @@ public class HibernateJpaDialect extends DefaultJpaDialect { private static class HibernateConnectionHandle implements ConnectionHandle { - @Nullable - private static volatile Method connectionMethodToUse; - - private final Session session; + private final SessionImplementor session; - public HibernateConnectionHandle(Session session) { + public HibernateConnectionHandle(SessionImplementor session) { this.session = session; } @Override public Connection getConnection() { - return doGetConnection(this.session); - } - - public static Connection doGetConnection(Session session) { - try { - Method methodToUse = connectionMethodToUse; - if (methodToUse == null) { - // Reflective lookup to find SessionImpl's connection() method on Hibernate 4.x/5.x - methodToUse = session.getClass().getMethod("connection"); - connectionMethodToUse = methodToUse; - } - Connection con = (Connection) ReflectionUtils.invokeMethod(methodToUse, session); - Assert.state(con != null, "No Connection from Session"); - return con; - } - catch (NoSuchMethodException ex) { - throw new IllegalStateException("Cannot find connection() method on Hibernate Session", ex); - } + return this.session.connection(); } }