hibernate/hibernate-orm · error · TransactionException

JTA TransactionManager.begin() failed

Error message

JTA TransactionManager.begin() failed

What it means

JtaTransactionAdapterTransactionManagerImpl.begin() calls TransactionManager.begin() only when it just observed status NOT_ACTIVE, and wraps any exception in this TransactionException, surfaced by Session.beginTransaction()/Transaction.begin() on a JTA coordinator. Either the status snapshot raced (a JTA transaction became associated between the getStatus() check and begin()) or the TransactionManager itself failed to begin (NotSupportedException/SystemException/IllegalStateException).

Source

Thrown at hibernate-core/src/main/java/org/hibernate/resource/transaction/backend/jta/internal/JtaTransactionAdapterTransactionManagerImpl.java:45

	public JtaTransactionAdapterTransactionManagerImpl(@Nonnull TransactionManager transactionManager) {
		this.transactionManager = transactionManager;
	}

	@Override
	public void begin() {
		try {
			if ( getStatus() == TransactionStatus.NOT_ACTIVE ) {
				JTA_LOGGER.callingTransactionManagerBegin();
				transactionManager.begin();
				initiator = true;
				JTA_LOGGER.calledTransactionManagerBegin();
			}
			else {
				JTA_LOGGER.skippingTransactionManagerBegin();
			}
		}
		catch (Exception e) {
			throw new TransactionException( "JTA TransactionManager.begin() failed", e );
		}
	}

	@Override
	public void commit() {
		try {
			if ( initiator ) {
				initiator = false;
				JTA_LOGGER.callingTransactionManagerCommit();
				transactionManager.commit();
				JTA_LOGGER.calledTransactionManagerCommit();
			}
			else {
				JTA_LOGGER.skippingTransactionManagerCommit();
			}
		}
		catch (Exception e) {
			throw new TransactionException( "JTA TransactionManager.commit() failed", e );

View on GitHub (pinned to fad1729dce)

Solutions

  1. Prefer container/Spring-managed transaction demarcation on JTA deployments and drop manual beginTransaction() calls
  2. Check status first and only begin when it is NOT_ACTIVE: session.getTransaction().getStatus()
  3. Verify hibernate.transaction.jta.platform resolves the container's real TransactionManager
  4. Restart or recover the TransactionManager if it reports SystemException

Example fix

// before
Session s = sf.openSession();
s.beginTransaction(); // races an already-active JTA transaction

// after
if ( s.getTransaction().getStatus() == TransactionStatus.NOT_ACTIVE ) {
    s.beginTransaction();
}
Defensive patterns

Strategy: validation

Validate before calling

// Only begin when Hibernate sees no active transaction
if ( session.getTransaction().getStatus() == TransactionStatus.NOT_ACTIVE ) {
    session.beginTransaction();
}
else {
    throw new IllegalStateException("A JTA transaction is already active; join it instead of beginning");
}

Try / catch

try {
    session.beginTransaction();
}
catch (TransactionException e) {
    Throwable c = e.getCause();
    if ( c instanceof IllegalStateException || c instanceof NotSupportedException ) {
        // a JTA transaction is already associated with this thread
    }
    throw e;
}

Prevention

When it happens

Trigger: session.beginTransaction() when a JTA transaction is already on the thread (container-managed transaction active, or a stale transaction left by thread-pool reuse), or the TM throws from begin() - TM stopped, nested begin unsupported, or internal error.

Common situations: Mixing manual Transaction.begin() with container-managed transactions on the same threads; pooled threads not cleaned after an incomplete transaction; a wrong JtaPlatform resolving a dead TransactionManager; SE setups where the TM was never started.

Related errors


AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22). Data as JSON: /api/errors/2ff93e54c81d4f78. Report an issue: GitHub.