HHH-13326 : Transaction passed to Hibernate Interceptor methods is null when JTA is used

(cherry picked from commit 883465f525)
This commit is contained in:
Gail Badner 2019-03-19 21:40:32 -07:00 committed by gbadner
parent 8aa976ea2d
commit 7559ecf196
2 changed files with 27 additions and 13 deletions

View File

@ -401,19 +401,25 @@ public abstract class AbstractSharedSessionContract implements SharedSessionCont
@Override @Override
public Transaction getTransaction() throws HibernateException { public Transaction getTransaction() throws HibernateException {
if ( getFactory().getSessionFactoryOptions().getJpaCompliance().isJpaTransactionComplianceEnabled() ) { if ( !isTransactionAccessible() ) {
// JPA requires that we throw IllegalStateException if this is called throw new IllegalStateException(
// on a JTA EntityManager "Transaction is not accessible when using JTA with JPA-compliant transaction access enabled"
if ( getTransactionCoordinator().getTransactionCoordinatorBuilder().isJta() ) { );
if ( !getFactory().getSessionFactoryOptions().isJtaTransactionAccessEnabled() ) {
throw new IllegalStateException( "A JTA EntityManager cannot use getTransaction()" );
}
}
} }
return accessTransaction(); 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 @Override
public Transaction accessTransaction() { public Transaction accessTransaction() {
if ( this.currentHibernateTransaction == null ) { if ( this.currentHibernateTransaction == null ) {

View File

@ -69,6 +69,7 @@ import org.hibernate.SessionEventListener;
import org.hibernate.SessionException; import org.hibernate.SessionException;
import org.hibernate.SharedSessionBuilder; import org.hibernate.SharedSessionBuilder;
import org.hibernate.SimpleNaturalIdLoadAccess; import org.hibernate.SimpleNaturalIdLoadAccess;
import org.hibernate.Transaction;
import org.hibernate.TransientObjectException; import org.hibernate.TransientObjectException;
import org.hibernate.TypeHelper; import org.hibernate.TypeHelper;
import org.hibernate.TypeMismatchException; import org.hibernate.TypeMismatchException;
@ -2472,13 +2473,20 @@ public final class SessionImpl
private transient LobHelperImpl lobHelper; 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 @Override
public void beforeTransactionCompletion() { public void beforeTransactionCompletion() {
log.tracef( "SessionImpl#beforeTransactionCompletion()" ); log.tracef( "SessionImpl#beforeTransactionCompletion()" );
flushBeforeTransactionCompletion(); flushBeforeTransactionCompletion();
actionQueue.beforeTransactionCompletion(); actionQueue.beforeTransactionCompletion();
try { try {
getInterceptor().beforeTransactionCompletion( getCurrentTransaction() ); getInterceptor().beforeTransactionCompletion( getTransactionIfAccessible() );
} }
catch (Throwable t) { catch (Throwable t) {
log.exceptionInBeforeTransactionCompletionInterceptor( t ); log.exceptionInBeforeTransactionCompletionInterceptor( t );
@ -2506,7 +2514,7 @@ public final class SessionImpl
} }
try { try {
getInterceptor().afterTransactionCompletion( getCurrentTransaction() ); getInterceptor().afterTransactionCompletion( getTransactionIfAccessible() );
} }
catch (Throwable t) { catch (Throwable t) {
log.exceptionInAfterTransactionCompletionInterceptor( t ); log.exceptionInAfterTransactionCompletionInterceptor( t );
@ -2727,7 +2735,7 @@ public final class SessionImpl
} }
actionQueue.beforeTransactionCompletion(); actionQueue.beforeTransactionCompletion();
try { try {
getInterceptor().beforeTransactionCompletion( getCurrentTransaction() ); getInterceptor().beforeTransactionCompletion( getTransactionIfAccessible() );
} }
catch (Throwable t) { catch (Throwable t) {
log.exceptionInBeforeTransactionCompletionInterceptor( t ); log.exceptionInBeforeTransactionCompletionInterceptor( t );
@ -3269,7 +3277,7 @@ public final class SessionImpl
@Override @Override
public void afterTransactionBegin() { public void afterTransactionBegin() {
checkOpenOrWaitingForAutoClose(); checkOpenOrWaitingForAutoClose();
getInterceptor().afterTransactionBegin( getCurrentTransaction() ); getInterceptor().afterTransactionBegin( getTransactionIfAccessible() );
} }
@Override @Override