diff --git a/hibernate-core/src/main/java/org/hibernate/internal/AbstractSharedSessionContract.java b/hibernate-core/src/main/java/org/hibernate/internal/AbstractSharedSessionContract.java index ee523b802d..8d9d530512 100644 --- a/hibernate-core/src/main/java/org/hibernate/internal/AbstractSharedSessionContract.java +++ b/hibernate-core/src/main/java/org/hibernate/internal/AbstractSharedSessionContract.java @@ -401,19 +401,25 @@ public abstract class AbstractSharedSessionContract implements SharedSessionCont @Override public Transaction getTransaction() throws HibernateException { - if ( getFactory().getSessionFactoryOptions().getJpaCompliance().isJpaTransactionComplianceEnabled() ) { - // JPA requires that we throw IllegalStateException if this is called - // on a JTA EntityManager - if ( getTransactionCoordinator().getTransactionCoordinatorBuilder().isJta() ) { - if ( !getFactory().getSessionFactoryOptions().isJtaTransactionAccessEnabled() ) { - throw new IllegalStateException( "A JTA EntityManager cannot use getTransaction()" ); - } - } + if ( !isTransactionAccessible() ) { + throw new IllegalStateException( + "Transaction is not accessible when using JTA with JPA-compliant transaction access enabled" + ); } - return accessTransaction(); } + protected boolean isTransactionAccessible() { + // JPA requires that access not be provided to the transaction when using JTA. + // This is overridden when SessionFactoryOptions isJtaTransactionAccessEnabled() is true. + if ( getFactory().getSessionFactoryOptions().getJpaCompliance().isJpaTransactionComplianceEnabled() && + getTransactionCoordinator().getTransactionCoordinatorBuilder().isJta() && + !getFactory().getSessionFactoryOptions().isJtaTransactionAccessEnabled() ) { + return false; + } + return true; + } + @Override public Transaction accessTransaction() { if ( this.currentHibernateTransaction == null ) { diff --git a/hibernate-core/src/main/java/org/hibernate/internal/SessionImpl.java b/hibernate-core/src/main/java/org/hibernate/internal/SessionImpl.java index 9a5b59b601..4f5a01f8db 100644 --- a/hibernate-core/src/main/java/org/hibernate/internal/SessionImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/internal/SessionImpl.java @@ -69,6 +69,7 @@ import org.hibernate.SessionEventListener; import org.hibernate.SessionException; import org.hibernate.SharedSessionBuilder; import org.hibernate.SimpleNaturalIdLoadAccess; +import org.hibernate.Transaction; import org.hibernate.TransientObjectException; import org.hibernate.TypeHelper; import org.hibernate.TypeMismatchException; @@ -2472,13 +2473,20 @@ public final class SessionImpl private transient LobHelperImpl lobHelper; + private Transaction getTransactionIfAccessible() { + // We do not want an exception to be thrown if the transaction + // is not accessible. If the transaction is not accessible, + // then return null. + return isTransactionAccessible() ? accessTransaction() : null; + } + @Override public void beforeTransactionCompletion() { log.tracef( "SessionImpl#beforeTransactionCompletion()" ); flushBeforeTransactionCompletion(); actionQueue.beforeTransactionCompletion(); try { - getInterceptor().beforeTransactionCompletion( getCurrentTransaction() ); + getInterceptor().beforeTransactionCompletion( getTransactionIfAccessible() ); } catch (Throwable t) { log.exceptionInBeforeTransactionCompletionInterceptor( t ); @@ -2506,7 +2514,7 @@ public final class SessionImpl } try { - getInterceptor().afterTransactionCompletion( getCurrentTransaction() ); + getInterceptor().afterTransactionCompletion( getTransactionIfAccessible() ); } catch (Throwable t) { log.exceptionInAfterTransactionCompletionInterceptor( t ); @@ -2727,7 +2735,7 @@ public final class SessionImpl } actionQueue.beforeTransactionCompletion(); try { - getInterceptor().beforeTransactionCompletion( getCurrentTransaction() ); + getInterceptor().beforeTransactionCompletion( getTransactionIfAccessible() ); } catch (Throwable t) { log.exceptionInBeforeTransactionCompletionInterceptor( t ); @@ -3269,7 +3277,7 @@ public final class SessionImpl @Override public void afterTransactionBegin() { checkOpenOrWaitingForAutoClose(); - getInterceptor().afterTransactionBegin( getCurrentTransaction() ); + getInterceptor().afterTransactionBegin( getTransactionIfAccessible() ); } @Override