quarkusio/quarkus · error · ContextNotActiveException
Cannot use the StatelessSession because neither a transactio
Error message
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.
What it means
TransactionScopedStatelessSession.acquireSession() resolves a StatelessSession either from an active JTA transaction or, when request-scoped sessions are enabled (quarkus.hibernate-orm.request-scoped.enabled=true), from an active CDI request context. When both are missing and request-scoped mode is enabled, it throws ContextNotActiveException telling you no usable scope exists. Called by refresh and all createQuery/createNamedQuery/createNativeQuery/stored-procedure methods.
Source
Thrown at extensions/hibernate-orm/runtime/src/main/java/io/quarkus/hibernate/orm/runtime/session/TransactionScopedStatelessSession.java:92
SessionResult acquireSession() {
// TODO: this was copied from TransactionScopedSession, but does it need to be the same???
if (isInTransaction()) {
StatelessSession session = (StatelessSession) transactionSynchronizationRegistry.getResource(sessionKey);
if (session != null) {
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.");
}View on GitHub (pinned to e1c734241f)
Solutions
- Annotate the calling method with @Transactional (most common fix)
- Annotate with @ActivateRequestContext if you intentionally want a request-scoped session without a transaction (request-scoped.enabled=true)
- Start a programmatic transaction with QuarkusTransaction.requiring(...) around the StatelessSession calls
- Check that the calling thread actually carries CDI request context if you expected it to (e.g. don't pass the bean into raw worker threads)
Example fix
// before
@Scheduled(every = "10s")
void cleanup() {
statelessSession.createQuery("delete from Token t where t.expiry < :now")...
}
// after
@Transactional
@Scheduled(every = "10s")
void cleanup() {
statelessSession.createQuery("delete from Token t where t.expiry < :now")...
} Defensive patterns
Strategy: validation
Validate before calling
import io.quarkus.arc.Arc;
import io.quarkus.narayana.jta.QuarkusTransaction;
boolean ok = QuarkusTransaction.isActive() || Arc.container().requestContext().isActive();
if (!ok) {
throw new IllegalStateException("StatelessSession needs @Transactional or @ActivateRequestContext here");
}
statelessSession.refresh(entity); Type guard
static boolean statelessSessionUsable() {
return io.quarkus.narayana.jta.QuarkusTransaction.isActive()
|| (io.quarkus.arc.Arc.container() != null
&& io.quarkus.arc.Arc.container().requestContext().isActive());
} Try / catch
try {
statelessSession.refresh(entity);
} catch (jakarta.enterprise.context.ContextNotActiveException e) {
io.quarkus.narayana.jta.QuarkusTransaction.requiring(() -> statelessSession.refresh(entity));
} Prevention
- Gate all StatelessSession access behind @Transactional service methods
- Never hand CDI beans to manually created threads (new Thread/ExecutorService) without activating a scope or transaction first
- In @Scheduled and reactive callbacks, add @Transactional explicitly — no context is active by default
- If you rely on @ActivateRequestContext, confirm quarkus.hibernate-orm.request-scoped.enabled=true
When it happens
Trigger: Invoking any StatelessSession operation (refresh, createQuery, createNamedQuery, createNativeQuery, createNamedStoredProcedureQuery, createStoredProcedureQuery) from a thread where no JTA transaction is active AND the CDI request context is not active, while request-scoped sessions are enabled.
Common situations: @Scheduled tasks, Vert.x event-loop or messaging (Kafka) callbacks without @Transactional, manually spawned ExecutorService threads, startup/init code (StartupEvent observers) that touches the StatelessSession before any scope is active.
Related errors
- Cannot use the StatelessSession because no transaction is ac
- This PersistenceProvider does not support createEntityManage
- Multiple instances of %1$s were found for persistence unit %
- Could not access JTA Transaction to register synchronization
- Not supported for JTA entity managers
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/b070c88382d2620a.
Report an issue: GitHub.