quarkusio/quarkus · error · TransactionRequiredException

Transaction is not active, consider adding @Transactional to

Error message

Transaction is not active, consider adding @Transactional to your method to automatically activate one.

What it means

StatelessSession refresh requires an active transaction in Quarkus' transaction-scoped session. When the acquired session reports allowModification=false (no active JTA transaction), Quarkus throws TransactionRequiredException with a message suggesting @Transactional.

Source

Thrown at extensions/hibernate-orm/runtime/src/main/java/io/quarkus/hibernate/orm/runtime/session/TransactionScopedStatelessSession.java:135

                case Status.STATUS_COMMITTING:
                case Status.STATUS_MARKED_ROLLBACK:
                case Status.STATUS_PREPARED:
                case Status.STATUS_PREPARING:
                    return true;
                default:
                    return false;
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public void refresh(Object entity) {
        checkBlocking();
        try (SessionResult emr = acquireSession()) {
            if (!emr.allowModification) {
                throw new TransactionRequiredException(TRANSACTION_IS_NOT_ACTIVE);
            }
            emr.statelessSession.refresh(entity);
        }
    }

    @Deprecated
    @Override
    public Query createQuery(String qlString) {
        checkBlocking();
        //TODO: this needs some thought for how it works outside a tx
        try (SessionResult emr = acquireSession()) {
            return emr.statelessSession.createQuery(qlString);
        }
    }

    @Override
    public <T> Query<T> createQuery(CriteriaQuery<T> criteriaQuery) {
        checkBlocking();

View on GitHub (pinned to e1c734241f)

Solutions

  1. Annotate the calling method (or class) with @jakarta.transaction.Transactional
  2. Join an existing transaction by calling refresh from within an already @Transactional bean method
  3. Start a transaction programmatically via UserTransaction before calling refresh

Example fix

// before
public Pet load(long id) {
    statelessSession.refresh(pet); // throws
}
// after
@Transactional
public Pet load(long id) {
    statelessSession.refresh(pet);
    return pet;
}
Defensive patterns

Strategy: validation

Validate before calling

if (!statelessSession.isJoinedToTransaction()) {
    throw new IllegalStateException("refresh() requires an active transaction; add @Transactional");
}
statelessSession.refresh(entity);

Try / catch

try {
    statelessSession.refresh(entity);
} catch (TransactionRequiredException e) {
    Log.error("No active transaction: " + e.getMessage());
}

Prevention

When it happens

Trigger: Calling statelessSession.refresh(entity) outside a transaction — no @Transactional on the method, no manually started transaction, or the transaction already committed/rolled back before the call.

Common situations: Calling refresh from a non-transactional CDI bean or REST method; forgetting @Transactional when migrating code that previously used a session-per-request pattern; calling refresh after the @Transactional method boundary (e.g. in a callback).

Related errors


AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05). Data as JSON: /api/errors/778e64d984db0a99. Report an issue: GitHub.