quarkusio/quarkus · error · ContextNotActiveException

Cannot use the StatelessSession because no transaction is ac

Error message

Cannot use the StatelessSession because no transaction is active. Consider adding @Transactional to your method to automatically activate a transaction, or set 'quarkus.hibernate-orm.request-scoped.enabled' to 'true' if you have valid reasons not to use transactions.

What it means

This is the sibling case of the ContextNotActiveException above, thrown when request-scoped sessions are DISABLED (the default, quarkus.hibernate-orm.request-scoped.enabled=false). TransactionScopedStatelessSession.acquireSession() can then only serve a session inside an active JTA transaction; with none active it throws ContextNotActiveException with the no-transaction message and points at the request-scoped.enabled property as the escape hatch. Triggered by any StatelessSession operation (refresh, createQuery, etc.) outside a transaction.

Source

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

                return new SessionResult(session, false, true);
            }
            StatelessSession newSession = jtaSessionOpener.openSession();
            // The session has automatically joined the JTA transaction when it was constructed.
            transactionSynchronizationRegistry.putResource(sessionKey, newSession);
            return new SessionResult(newSession, false, true);
        } else if (requestScopedSessionEnabled) {
            if (Arc.container().requestContext().isActive()) {
                RequestScopedStatelessSessionHolder requestScopedSessions = this.requestScopedSessions.get();
                return new SessionResult(requestScopedSessions.getOrCreateSession(unitName, sessionFactory),
                        false, false);
            } else {
                throw new ContextNotActiveException(
                        "Cannot use the StatelessSession because neither a transaction nor a CDI request context is active."
                                + " Consider adding @Transactional to your method to automatically activate a transaction,"
                                + " or @ActivateRequestContext if you have valid reasons not to use transactions.");
            }
        } else {
            throw new ContextNotActiveException(
                    "Cannot use the StatelessSession because no transaction is active."
                            + " Consider adding @Transactional to your method to automatically activate a transaction,"
                            + " or set '" + HibernateOrmRuntimeConfig.extensionPropertyKey("request-scoped.enabled")
                            + "' to 'true' if you have valid reasons not to use transactions.");
        }
    }

    private void checkBlocking() {
        if (!BlockingOperationControl.isBlockingAllowed()) {
            throw new BlockingOperationNotAllowedException(
                    "You have attempted to perform a blocking operation on a IO thread. This is not allowed, as blocking the IO thread will cause major performance issues with your application. If you want to perform blocking StatelessSession operations make sure you are doing it from a worker thread.");
        }
    }

    private boolean isInTransaction() {
        try {
            switch (transactionManager.getStatus()) {
                case Status.STATUS_ACTIVE:

View on GitHub (pinned to e1c734241f)

Solutions

  1. Add @Transactional to the method performing StatelessSession operations
  2. Start/commit a transaction programmatically via QuarkusTransaction.requiring(...) or begin()/commit()
  3. Set quarkus.hibernate-orm.request-scoped.enabled=true (plus @ActivateRequestContext or an active request context) if you deliberately want transaction-less session usage
  4. Remove @ActivateRequestContext misuse — with request-scoped.enabled=false it does not help; either enable the property or use a transaction

Example fix

// before
public void purgeExpired() {
    statelessSession.createQuery("delete from Session s where s.expires < :t")...
}
// after
@Transactional
public void purgeExpired() {
    statelessSession.createQuery("delete from Session s where s.expires < :t")...
}
Defensive patterns

Strategy: validation

Validate before calling

import io.quarkus.narayana.jta.QuarkusTransaction;
if (!QuarkusTransaction.isActive()) {
    QuarkusTransaction.requiring(() -> {
        statelessSession.createQuery("delete from X", Void.class).executeUpdate();
    });
} else {
    statelessSession.createQuery("delete from X", Void.class).executeUpdate();
}

Type guard

static boolean transactionActiveForStatelessSession() {
    return io.quarkus.narayana.jta.QuarkusTransaction.isActive();
}

Try / catch

try {
    statelessSession.refresh(entity);
} catch (jakarta.enterprise.context.ContextNotActiveException e) {
    // request-scoped mode disabled: a transaction is mandatory
    io.quarkus.narayana.jta.QuarkusTransaction.requiring(() -> statelessSession.refresh(entity));
}

Prevention

When it happens

Trigger: Any StatelessSession use (refresh, createQuery, createNamedQuery, createNativeQuery, createNamedStoredProcedureQuery, createStoredProcedureQuery) when no JTA transaction is active and 'quarkus.hibernate-orm.request-scoped.enabled' is false (the default).

Common situations: Unannotated REST/GraphQL handlers, @Scheduled jobs, reactive pipelines continuing on a different thread after the transaction ended, background processors, or code that used @ActivateRequestContext but left request-scoped mode disabled so the request-context branch never applies.

Related errors


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