hibernate/hibernate-orm · error · IllegalStateException
Transaction already active (in JPA compliant mode)
Error message
Transaction already active (in JPA compliant mode)
What it means
TransactionImpl.begin() detects that a transaction is already active. When the session factory runs with JPA transaction compliance enabled (hibernate.jpa.compliance.transaction=true, the default for JPA-bootstrapped factories), re-beginning violates the JPA contract, so an IllegalStateException is thrown instead of joining.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/engine/transaction/internal/TransactionImpl.java:71
if ( CORE_LOGGER.isDebugEnabled() && jpaCompliance ) {
CORE_LOGGER.transactionCreatedInJpaCompliantMode();
}
}
@Override
public void begin() {
if ( !session.isOpen() ) {
throw new IllegalStateException( "Cannot begin Transaction on closed Session/EntityManager" );
}
if ( transactionDriverControl == null ) {
transactionDriverControl =
transactionCoordinator.getTransactionDriverControl();
}
if ( isActive() ) {
if ( jpaCompliance ) {
throw new IllegalStateException( "Transaction already active (in JPA compliant mode)" );
}
else if ( !transactionCoordinator.getTransactionCoordinatorBuilder().isJta() ) {
throw new IllegalStateException( "Resource-local transaction already active" );
}
}
else {
CORE_LOGGER.beginningTransaction();
transactionDriverControl.begin();
}
}
@Override
public void commit() {
// allow MARKED_ROLLBACK to propagate through to transactionDriverControl
if ( !isActive() ) {
// we have a transaction that is inactive and has not been marked for rollback only
throw new IllegalStateException( "Transaction not successfully started" );
}View on GitHub (pinned to fad1729dce)
Solutions
- Guard with if (!tx.isActive()) tx.begin() so an existing transaction is joined rather than re-begun
- Let the container/framework own transaction demarcation (@Transactional) and delete the manual begin()
- Ensure every begin() has a matching commit/rollback path so the next begin() starts clean
Example fix
// before
Transaction tx = em.getTransaction();
tx.begin();
doWork();
tx.begin(); // JPA-compliant mode -> IllegalStateException
// after
Transaction tx = em.getTransaction();
if (!tx.isActive()) {
tx.begin();
}
doWork(); Defensive patterns
Strategy: validation
Validate before calling
if (!tx.isActive()) {
tx.begin();
} Prevention
- Wrap begin() in a single 'ensureTransaction' helper and call it instead of raw begin()
- Let @Transactional own demarcation; remove manual begin() from managed beans
- Always close the transaction (commit/rollback) before the next unit of work on the same EM
When it happens
Trigger: Calling getTransaction().begin() a second time without an intervening commit/rollback on the same EntityManager while jpaCompliance is on; a manual begin() racing with container- or framework-managed transaction start (@Transactional, JTA-bound EM).
Common situations: Helper methods that 'ensure' a transaction by calling begin() unconditionally inside nested service calls; mixing manual EM transaction control with Spring/JTA-managed transactions; upgrading native Hibernate code to JPA-compliant settings; retry wrappers that restart logic without resetting the EM.
Related errors
- Resource-local transaction already active
- rollback() called on inactive transaction (in JPA compliant
- setRollbackOnly() called on inactive transaction (in JPA com
- getRollbackOnly() called on inactive transaction (in JPA com
- Newer version [" + latestVersion + "] of entity [" + infoStr
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/89ce820910da5ed2.
Report an issue: GitHub.