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
- Add @Transactional to the method performing StatelessSession operations
- Start/commit a transaction programmatically via QuarkusTransaction.requiring(...) or begin()/commit()
- Set quarkus.hibernate-orm.request-scoped.enabled=true (plus @ActivateRequestContext or an active request context) if you deliberately want transaction-less session usage
- 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
- Keep request-scoped.enabled=false (default) and always use @Transactional with StatelessSession — the simplest, safest pattern
- Avoid @ActivateRequestContext as a fix unless you also enable quarkus.hibernate-orm.request-scoped.enabled
- Wrap programmatic usage in QuarkusTransaction.requiring(...) so missing transactions fail fast at the boundary
- Audit async code paths (continuations, executors) for lost transaction context before session use
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
- Cannot use the StatelessSession because neither a transactio
- Not supported for JTA entity managers
- Could not access JTA Transaction to register synchronization
- Not supported for JTA entity managers
- Driver is not an XA dataSource, while XA has been enabled in
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/b37749e211ac8d8b.
Report an issue: GitHub.