{"record":{"id":"af8061253451b265","repo":"quarkusio/quarkus","slug":"cannot-use-the-entitymanager-session-because-neith","errorCode":null,"errorMessage":"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.","messagePattern":"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\\.","errorType":"exception","errorClass":"ContextNotActiveException","httpStatus":null,"severity":"error","filePath":"extensions/hibernate-orm/runtime/src/main/java/io/quarkus/hibernate/orm/runtime/session/TransactionScopedSession.java","lineNumber":125,"sourceCode":"            }\n            Session newSession = jtaSessionOpener.openSession();\n            // The session has automatically joined the JTA transaction when it was constructed.\n            transactionSynchronizationRegistry.putResource(sessionKey, newSession);\n            // No need to flush or close the session upon transaction completion:\n            // Hibernate ORM itself registers a transaction that does just that.\n            // See:\n            // - io.quarkus.hibernate.orm.runtime.boot.FastBootMetadataBuilder.mergeSettings\n            // - org.hibernate.resource.transaction.backend.jta.internal.JtaTransactionCoordinatorImpl.joinJtaTransaction\n            // - org.hibernate.internal.SessionImpl.beforeTransactionCompletion\n            // - org.hibernate.internal.SessionImpl.afterTransactionCompletion\n            return new SessionResult(newSession, false, true);\n        } else if (requestScopedSessionEnabled) {\n            if (Arc.container().requestContext().isActive()) {\n                RequestScopedSessionHolder requestScopedSessions = this.requestScopedSessions.get();\n                return new SessionResult(requestScopedSessions.getOrCreateSession(unitName, sessionFactory),\n                        false, false);\n            } else {\n                throw new ContextNotActiveException(\n                        \"Cannot use the EntityManager/Session because neither a transaction nor a CDI request context is active.\"\n                                + \" Consider adding @Transactional to your method to automatically activate a transaction,\"\n                                + \" or @ActivateRequestContext if you have valid reasons not to use transactions.\");\n            }\n        } else {\n            throw new ContextNotActiveException(\n                    \"Cannot use the EntityManager/Session because no transaction is active.\"\n                            + \" Consider adding @Transactional to your method to automatically activate a transaction,\"\n                            + \" or set '\" + HibernateOrmRuntimeConfig.extensionPropertyKey(\"request-scoped.enabled\")\n                            + \"' to 'true' if you have valid reasons not to use transactions.\");\n        }\n    }\n\n    private void checkBlocking() {\n        if (!BlockingOperationControl.isBlockingAllowed()) {\n            throw new BlockingOperationNotAllowedException(\n                    \"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.\");\n        }","sourceCodeStart":107,"sourceCodeEnd":143,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/hibernate-orm/runtime/src/main/java/io/quarkus/hibernate/orm/runtime/session/TransactionScopedSession.java#L107-L143","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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."],"exampleFix":"// before\n@Scheduled(every = \"10s\")\nvoid cleanup() {\n    em.remove(stale); // ContextNotActiveException\n}\n\n// after\n@Scheduled(every = \"10s\")\n@Transactional\nvoid cleanup() {\n    em.remove(stale);\n}","handlingStrategy":"validation","validationCode":"import io.quarkus.arc.Arc;\n\nboolean safeToUseEm() {\n    return Arc.container().requestContext().isActive()\n        || Arc.container().beanManager()\n              .resolveBeanManager() != null && isTransactionActive();\n}\n// Simplest pre-check before any EM call on background threads:\nboolean requestActive() {\n    return Arc.container() != null && Arc.container().requestContext().isActive();\n}","typeGuard":null,"tryCatchPattern":"try {\n    em.persist(entity);\n} catch (ContextNotActiveException e) {\n    // request context not active: fall back to a transactional bean call\n    transactionalService.persist(entity);\n}","preventionTips":["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."],"tags":["cdi","hibernate-orm","request-context","transactions"],"backgroundTag":"cdi-context-not-active","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}