hibernate/hibernate-orm · error · IllegalStateException
setRollbackOnly() called on inactive transaction (in JPA com
Error message
setRollbackOnly() called on inactive transaction (in JPA compliant mode)
What it means
setRollbackOnly() is the JPA-defined way to mark a transaction rollback-only, and JPA requires an active transaction. In JPA-compliance mode TransactionImpl throws IllegalStateException when the transaction is inactive; in native mode it just logs setRollbackOnlyCalledOnInactiveTransaction and continues (equivalent to the lenient markRollbackOnly()).
Source
Thrown at hibernate-core/src/main/java/org/hibernate/engine/transaction/internal/TransactionImpl.java:202
@Override
public void markRollbackOnly() {
// This is the Hibernate-specific API, whereas setRollbackOnly is the
// JPA-defined API. In our opinion, it's much more user-friendly to
// always allow the client to indicate that the transaction should
// not be allowed to commit.
if ( isActive() ) {
internalGetTransactionDriverControl().markRollbackOnly();
}
// else noop for an inactive transaction
}
@Override
public void setRollbackOnly() {
if ( !isActive() ) {
if ( jpaCompliance ) {
// This is the JPA-defined version of this operation,
// so we must check that the transaction is active
throw new IllegalStateException( "setRollbackOnly() called on inactive transaction (in JPA compliant mode)" );
}
else {
// JpaCompliance disables the check, so this method
// is equivalent to our native markRollbackOnly()
CORE_LOGGER.setRollbackOnlyCalledOnInactiveTransaction();
}
}
else {
markRollbackOnly();
}
}
@Override
public boolean getRollbackOnly() {
if ( jpaCompliance && !isActive() ) {
throw new IllegalStateException( "getRollbackOnly() called on inactive transaction (in JPA compliant mode)" );
}
else {View on GitHub (pinned to fad1729dce)
Solutions
- Guard the call: if (tx.isActive()) { tx.setRollbackOnly(); }
- Prefer native markRollbackOnly() when lenient behavior is desired across mixed paths
- Move setRollbackOnly() into the branch that actually owns the failed transaction
Example fix
// before
catch (BusinessException e) {
tx.setRollbackOnly(); // inactive tx, JPA mode -> IllegalStateException
}
// after
catch (BusinessException e) {
if (tx.isActive()) {
tx.setRollbackOnly();
}
} Defensive patterns
Strategy: validation
Validate before calling
if (tx.isActive()) {
tx.setRollbackOnly();
} Prevention
- Guard setRollbackOnly() with isActive() in shared handlers
- Prefer native markRollbackOnly() for lenient behavior outside transactions
- Mark rollback-only only in the branch that owns the failed transaction
When it happens
Trigger: tx.setRollbackOnly() called before begin() or after commit()/rollback() completed, with hibernate.jpa.compliance.transaction=true.
Common situations: Exception handlers marking rollback-only even on paths where no transaction ever started; shared validation/audit code running both inside and outside transactions; retry loops calling setRollbackOnly before restarting work.
Related errors
- getRollbackOnly() called on inactive transaction (in JPA com
- rollback() called on inactive transaction (in JPA compliant
- Transaction already active (in JPA compliant mode)
- Transaction was marked for rollback only
- Newer version [" + latestVersion + "] of entity [" + infoStr
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/85d40cdecf29b248.
Report an issue: GitHub.