hibernate/hibernate-orm · error · TransactionException
JTA UserTransaction.begin() failed
Error message
JTA UserTransaction.begin() failed
What it means
The UserTransaction-based JTA adapter's begin(): it calls UserTransaction.begin() when it just observed status NOT_ACTIVE and wraps any exception in this TransactionException. UserTransaction is the application-facing JTA handle; the wrapped exception (NotSupportedException/SystemException/IllegalStateException) means the UT refused to start a transaction - commonly because a transaction is already associated with the thread or the UT is unusable in the current context.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/resource/transaction/backend/jta/internal/JtaTransactionAdapterUserTransactionImpl.java:46
public JtaTransactionAdapterUserTransactionImpl(@Nonnull UserTransaction userTransaction) {
this.userTransaction = userTransaction;
}
@Override
public void begin() {
try {
if ( getStatus() == TransactionStatus.NOT_ACTIVE ) {
JTA_LOGGER.callingUserTransactionBegin();
userTransaction.begin();
initiator = true;
JTA_LOGGER.calledUserTransactionBegin();
}
else {
JTA_LOGGER.skippingTransactionManagerBegin();
}
}
catch (Exception e) {
throw new TransactionException( "JTA UserTransaction.begin() failed", e );
}
}
@Override
public void commit() {
try {
if ( initiator ) {
initiator = false;
JTA_LOGGER.callingUserTransactionCommit();
userTransaction.commit();
JTA_LOGGER.calledUserTransactionCommit();
}
else {
JTA_LOGGER.skippingTransactionManagerCommit();
}
}
catch (Exception e) {
throw new TransactionException( "JTA UserTransaction.commit() failed", e );View on GitHub (pinned to fad1729dce)
Solutions
- Check UserTransaction.getStatus() before beginning; only begin when no transaction is active
- Drop the preferUserTransactions setting so the coordinator drives the TransactionManager instead
- Verify the JNDI name / JtaPlatform used to obtain the UserTransaction
- Use container-managed transaction demarcation in EE environments
Example fix
// before
UserTransaction ut = ...;
ut.begin(); // inside an already-active container-managed tx
// after
if ( ut.getStatus() == jakarta.transaction.Status.STATUS_NO_TRANSACTION ) {
ut.begin();
} Defensive patterns
Strategy: validation
Validate before calling
// Only begin via UserTransaction when none is active
if ( ut.getStatus() == jakarta.transaction.Status.STATUS_NO_TRANSACTION ) {
ut.begin();
}
else {
throw new IllegalStateException("A JTA transaction is already active");
} Try / catch
try {
session.beginTransaction();
}
catch (TransactionException e) {
Throwable c = e.getCause();
if ( c instanceof IllegalStateException || c instanceof NotSupportedException ) {
// UserTransaction refused: a tx is already associated or UT unusable here
}
throw e;
} Prevention
- Do not begin transactions on threads already carrying a container-managed JTA transaction
- In SE, prefer the TransactionManager-based coordinator over preferUserTransactions
- Verify the UserTransaction JNDI binding is valid for the calling context
When it happens
Trigger: Transaction.begin() on a session whose coordinator prefers UserTransactions (preferUserTransactions) when UserTransaction.begin() throws: a container-managed transaction already active on the thread (raced status check), the container forbidding user transactions on that thread, or the UT not bound/usable.
Common situations: Calling beginTransaction() during a container-managed transaction; a UserTransaction JNDI binding valid only inside EE components; invoking from unmanaged threads; SE setups with no bound UserTransaction.
Related errors
- JTA TransactionManager.begin() failed
- JTA UserTransaction.commit() failed
- JTA UserTransaction.rollback() failed
- UserTransaction reported transaction status as unknown
- JTA UserTransaction.getStatus() failed
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/46a1a495f64824d2.
Report an issue: GitHub.