quarkusio/quarkus · error · ContextNotActiveException
Cannot use the EntityManager/Session because no transaction
Error message
Cannot use the EntityManager/Session 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 default-path failure of acquireSession in TransactionScopedSession: when request-scoped sessions are disabled (the default, quarkus.hibernate-orm.request-scoped.enabled=false), a session may ONLY be obtained inside an active transaction. Any EntityManager operation issued outside @Transactional therefore throws ContextNotActiveException, pointing the developer at @Transactional or at enabling request-scoped sessions.
Source
Thrown at extensions/hibernate-orm/runtime/src/main/java/io/quarkus/hibernate/orm/runtime/session/TransactionScopedSession.java:131
// 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.");
}
}
private boolean isInTransaction() {
try {
switch (transactionManager.getStatus()) {
case Status.STATUS_ACTIVE:View on GitHub (pinned to e1c734241f)
Solutions
- Add @Transactional to the method performing the EntityManager call (writes require it; reads also get a session this way).
- If you need read-only EM usage without transactions, set quarkus.hibernate-orm.request-scoped.enabled=true so a request-context session is used instead.
- Ensure the call runs inside a CDI-managed bean (REST resource, @ApplicationScoped service) so the ArC interceptor for @Transactional fires — direct calls on `new MyService()` bypass interception.
- For programmatic control, use the injected Session/EntityManager within a UserTransaction or annotate a smaller inner method to scope the transaction.
Example fix
// before
@ApplicationScoped
public class UserRepository {
@Inject EntityManager em;
public void save(User u) {
em.persist(u); // ContextNotActiveException
}
}
// after
@ApplicationScoped
public class UserRepository {
@Inject EntityManager em;
@Transactional
public void save(User u) {
em.persist(u);
}
} Defensive patterns
Strategy: validation
Validate before calling
boolean emUsableWithoutRequestScope() {
// request-scoped disabled (default): EM only works inside a transaction
return quarkusTransactionActive();
}
// e.g. check via the injected EntityManager is not possible; check transaction status:
boolean inTx() {
return !TransactionManager.instance().getStatus()
.map(s -> s == Status.STATUS_NO_TRANSACTION).orElse(true);
} Try / catch
try {
em.find(User.class, id);
} catch (ContextNotActiveException e) {
// no transaction: retry through a @Transactional service
return userRepository.find(id);
} Prevention
- Default to annotating every EM-touching method with @Transactional.
- Enable quarkus.hibernate-orm.request-scoped.enabled=true only if you fully understand the read-only implication.
- Never instantiate CDI beans with `new`; let the container apply transaction interceptors.
- Cover each EM call path with a test that starts the app (e.g. @QuarkusTest) to catch missing transactions early.
When it happens
Trigger: Injecting EntityManager (backed by TransactionScopedSession) and calling persist/merge/remove/find/findMultiple/getReference from code with no active transaction and request-scoped sessions disabled — e.g. a REST resource method without @Transactional, a scheduled job, a startup observer, or a Vert.x route handler calling the EM directly.
Common situations: Forgetting @Transactional on a service method that writes; calling the EM from a QuarkusTest before the request/transaction scope starts; migrating code that used @Inject EntityManager expecting an application-scoped session; enabling/disabling request-scoped.enabled across versions and changing behavior.
Related errors
- Cannot use the EntityManager/Session because neither a trans
- 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/5f32522609e51515.
Report an issue: GitHub.