hibernate/hibernate-orm · error · TransactionRequiredForJoinException
Explicitly joining a JTA transaction requires a JTA transact
Error message
Explicitly joining a JTA transaction requires a JTA transaction be currently active
What it means
JtaTransactionCoordinatorImpl.explicitJoin() runs when the session is not yet enlisted in a JTA transaction (synchronizationRegistered == false). If the physical delegate's status is not ACTIVE it throws TransactionRequiredForJoinException: you asked to join a JTA transaction, but none is currently active on the thread. It surfaces from EntityManager.joinTransaction()/Session transaction join, most often for UNSYNCHRONIZED persistence contexts.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/resource/transaction/backend/jta/internal/JtaTransactionCoordinatorImpl.java:172
if ( !synchronizationRegistered ) {
jtaPlatform.registerSynchronization(
new RegisteredSynchronization( getSynchronizationCallbackCoordinator() ) );
getSynchronizationCallbackCoordinator().synchronizationRegistered();
synchronizationRegistered = true;
JTA_LOGGER.registeredSynchronization();
// report entering into a "transactional context"
getTransactionCoordinatorOwner().startTransactionBoundary();
}
}
@Override
public void explicitJoin() {
if ( synchronizationRegistered ) {
JTA_LOGGER.alreadyJoinedJtaTransaction();
}
else {
if ( getTransactionDriverControl().getStatus() != ACTIVE ) {
throw new TransactionRequiredForJoinException(
"Explicitly joining a JTA transaction requires a JTA transaction be currently active"
);
}
joinJtaTransaction();
}
}
@Override
public boolean isJoined() {
return synchronizationRegistered;
}
/**
* Is the RegisteredSynchronization used by Hibernate for unified JTA Synchronization callbacks registered for this
* coordinator?
*
* @return {@code true} indicates that a RegisteredSynchronization is currently registered for this coordinator;
* {@code false} indicates it is not (yet) registered.View on GitHub (pinned to fad1729dce)
Solutions
- Start the JTA transaction first (JTA-based @Transactional or UserTransaction.begin()) and only then call joinTransaction
- With Spring, use JtaTransactionManager so Spring-managed transactions are JTA transactions
- If JTA is not intended, configure Hibernate with the JDBC/resource-local transaction coordinator instead of jta
- Guard with a TransactionManager status check before joining (see validation)
Example fix
// before
em.joinTransaction(); // throws if no JTA transaction is active
// after
if ( !em.isJoinedToTransaction() ) {
if ( tm.getStatus() == jakarta.transaction.Status.STATUS_ACTIVE ) {
em.joinTransaction();
}
else {
ut.begin();
try {
em.joinTransaction();
}
catch (RuntimeException e) {
ut.rollback();
throw e;
}
}
} Defensive patterns
Strategy: validation
Validate before calling
// Run this before em.joinTransaction()
try {
if ( !em.isJoinedToTransaction()
&& transactionManager.getStatus() != jakarta.transaction.Status.STATUS_ACTIVE ) {
throw new IllegalStateException("Start the JTA transaction before joining");
}
}
catch (SystemException e) {
throw new IllegalStateException("Cannot determine JTA status", e);
}
em.joinTransaction(); Try / catch
try {
em.joinTransaction();
}
catch (TransactionRequiredForJoinException e) {
// no JTA tx on the thread: start one (or run under JTA-based @Transactional) and retry once
ut.begin();
try {
em.joinTransaction();
}
catch (RuntimeException re) {
ut.rollback();
throw re;
}
} Prevention
- Always run joinTransaction() inside a JTA-based transactional scope (@Transactional, UserTransaction.begin, CMT)
- With Spring, pair a JTA-configured Hibernate with JtaTransactionManager
- Prefer SYNCHRONIZED persistence contexts unless you explicitly manage joining
When it happens
Trigger: em.joinTransaction() executed where no JTA transaction is active: code not running under a JTA-based @Transactional or UserTransaction.begin(); the container transaction already completed (e.g., timed out); async threads without a propagated transaction; Spring using a non-JTA PlatformTransactionManager while Hibernate is JTA-configured.
Common situations: SynchronizationType.UNSYNCHRONIZED EntityManagers calling joinTransaction at a point where the surrounding transaction has not started; Spring's DataSourceTransactionManager or HibernateTransactionManager with a jta coordinator_class; SE code forgetting UserTransaction.begin(); joining after a timeout completed the transaction.
Related errors
- Transaction is not accessible when using JTA with JPA-compli
- Exception pulsing TransactionCoordinator
- Explicitly joining a JTA transaction requires a JTA transact
- Unable to start isolated transaction
- Error performing work
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/b47eaf46d53213e4.
Report an issue: GitHub.