quarkusio/quarkus · error · ContextNotActiveException
Cannot use the EntityManager/Session because neither a trans
Error message
Cannot use the EntityManager/Session 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
TransactionScopedSession is the CDI bean backing @Inject EntityManager. When acquiring a session it first allows an active transaction; failing that, it allows a session-scoped fallback only if request-scoped sessions are enabled AND the CDI request context is active. If request-scoped sessions are enabled but no request context is active (e.g. a background thread, startup event, or scheduler), Quarkus throws ContextNotActiveException because the session could not be kept per-request consistent.
Source
Thrown at extensions/hibernate-orm/runtime/src/main/java/io/quarkus/hibernate/orm/runtime/session/TransactionScopedSession.java:125
}
Session newSession = jtaSessionOpener.openSession();
// The session has automatically joined the JTA transaction when it was constructed.
transactionSynchronizationRegistry.putResource(sessionKey, newSession);
// No need to flush or close the session upon transaction completion:
// Hibernate ORM itself registers a transaction that does just that.
// See:
// - io.quarkus.hibernate.orm.runtime.boot.FastBootMetadataBuilder.mergeSettings
// - org.hibernate.resource.transaction.backend.jta.internal.JtaTransactionCoordinatorImpl.joinJtaTransaction
// - org.hibernate.internal.SessionImpl.beforeTransactionCompletion
// - org.hibernate.internal.SessionImpl.afterTransactionCompletion
return new SessionResult(newSession, false, true);
} else if (requestScopedSessionEnabled) {
if (Arc.container().requestContext().isActive()) {
RequestScopedSessionHolder requestScopedSessions = this.requestScopedSessions.get();
return new SessionResult(requestScopedSessions.getOrCreateSession(unitName, sessionFactory),
false, false);
} else {
throw new ContextNotActiveException(
"Cannot use the EntityManager/Session 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 EntityManager/Session 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 EntityManager operations make sure you are doing it from a worker thread.");
}View on GitHub (pinned to e1c734241f)
Solutions
- Annotate the method (or class) with @Transactional so acquireSession takes the transaction path instead of the request-context path.
- Wrap the method in @ActivateRequestContext if you deliberately want a request-scoped session without a transaction (finds/reads only; writes still need a transaction).
- Move the ORM work into a request-scoped or transactional CDI bean rather than running it directly on a background/event-loop thread.
- If sessions should only be transaction-scoped, set quarkus.hibernate-orm.request-scoped.enabled=false so the error points to the missing transaction instead.
Example fix
// before
@Scheduled(every = "10s")
void cleanup() {
em.remove(stale); // ContextNotActiveException
}
// after
@Scheduled(every = "10s")
@Transactional
void cleanup() {
em.remove(stale);
} Defensive patterns
Strategy: validation
Validate before calling
import io.quarkus.arc.Arc;
boolean safeToUseEm() {
return Arc.container().requestContext().isActive()
|| Arc.container().beanManager()
.resolveBeanManager() != null && isTransactionActive();
}
// Simplest pre-check before any EM call on background threads:
boolean requestActive() {
return Arc.container() != null && Arc.container().requestContext().isActive();
} Try / catch
try {
em.persist(entity);
} catch (ContextNotActiveException e) {
// request context not active: fall back to a transactional bean call
transactionalService.persist(entity);
} Prevention
- Always pair injected-EntityManager usage with @Transactional in non-HTTP code (schedulers, consumers, startup events).
- Never call the transaction-scoped EntityManager directly from Vert.x event loops or hand-rolled threads; go through a CDI bean method.
- If enabling quarkus.hibernate-orm.request-scoped.enabled, audit all EM call sites for an active request context.
- Add an integration test that runs the ORM code path from the same thread/scope as production.
When it happens
Trigger: Calling any TransactionScopedSession method (persist, merge, remove, find, findMultiple, getReference) via an injected EntityManager when: quarkus.hibernate-orm.request-scoped.enabled=true, there is no active @Transactional, and Arc.container().requestContext().isActive() is false — typically code running on a non-HTTP thread (Vert.x event loop/callback, @Scheduled executor, manually spawned thread, or outside a request scope).
Common situations: Running Hibernate calls from a @Scheduled task or Kafka/Vert.x message consumer without @Transactional; doing ORM work in an ApplicationStarted observer or on a plain new Thread; unit-style code calling the injected EM during startup; tests that invoke EM methods outside a request scope.
Related errors
- Cannot use the EntityManager/Session because no transaction
- This PersistenceProvider does not support createEntityManage
- Multiple instances of %1$s were found for persistence unit %
- Transaction is not active, consider adding @Transactional to
- Not supported for JTA entity managers
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/af8061253451b265.
Report an issue: GitHub.