{"record":{"id":"04236c6c19fbf801","repo":"flowable/flowable-engine","slug":"error-while-closing-entitymanager-may-have-alread-04236c","errorCode":null,"errorMessage":"Error while closing EntityManager, may have already been closed or it is container-managed","messagePattern":"Error while closing EntityManager, may have already been closed or it is container-managed","errorType":"exception","errorClass":"ActivitiException","httpStatus":null,"severity":"error","filePath":"modules/flowable5-engine/src/main/java/org/activiti/engine/impl/variable/EntityManagerSessionImpl.java","lineNumber":79,"sourceCode":"                throw new ActivitiException(\"Error while flushing EntityManager: \" + pe.getMessage(), pe);\n            }\n        }\n    }\n\n    protected boolean isTransactionActive() {\n        if (handleTransactions && entityManager.getTransaction() != null) {\n            return entityManager.getTransaction().isActive();\n        }\n        return false;\n    }\n\n    @Override\n    public void close() {\n        if (closeEntityManager && entityManager != null && !entityManager.isOpen()) {\n            try {\n                entityManager.close();\n            } catch (IllegalStateException ise) {\n                throw new ActivitiException(\"Error while closing EntityManager, may have already been closed or it is container-managed\", ise);\n            }\n        }\n    }\n\n    @Override\n    public EntityManager getEntityManager() {\n        if (entityManager == null) {\n            entityManager = getEntityManagerFactory().createEntityManager();\n\n            if (handleTransactions) {\n                // Add transaction listeners, if transactions should be handled\n                TransactionListener jpaTransactionCommitListener = new TransactionListener() {\n                    @Override\n                    public void execute(CommandContext commandContext) {\n                        if (isTransactionActive()) {\n                            entityManager.getTransaction().commit();\n                        }\n                    }","sourceCodeStart":61,"sourceCodeEnd":97,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable5-engine/src/main/java/org/activiti/engine/impl/variable/EntityManagerSessionImpl.java#L61-L97","documentation":"Thrown by EntityManagerSessionImpl.close() when EntityManager.close() raises IllegalStateException. This happens for application-managed EntityManagers that are already closed, or container-managed ones that must not be closed by application code. The engine rethrows it as ActivitiException.","triggerScenarios":"close() invoked with closeEntityManager=true while the EntityManager is already closed; using a container-managed (JTA) EntityManager and letting the engine attempt close; double-close of the session.","commonSituations":"Spring-managed shared EntityManager passed to EntityManagerSessionFactory with closeEntityManager=true; session closed twice; application closed the EM before the engine session teardown.","solutions":["Set closeEntityManager=false on EntityManagerSessionFactory when the container manages the EntityManager lifecycle","Avoid closing the EntityManager manually while the engine session still owns it","Check for duplicate session close calls in custom command interceptors","Upgrade container integration (e.g. SpringEntityManagerSessionFactory) to manage close correctly"],"exampleFix":"// before\nnew EntityManagerSessionFactory(emf, false, true); // engine closes container-managed EM\n// after\nnew EntityManagerSessionFactory(emf, false, false); // container closes it","handlingStrategy":"type-guard","validationCode":"if (entityManager != null && !entityManager.isOpen()) {\n    throw new IllegalStateException(\"EntityManager already closed; do not let engine close container-managed EMs\");\n}","typeGuard":"boolean safeToClose = closeEntityManager && entityManager != null && entityManager.isOpen();","tryCatchPattern":"try {\n    session.close();\n} catch (ActivitiException e) {\n    if (e.getCause() instanceof IllegalStateException) {\n        // treat as already closed: log and continue\n    }\n}","preventionTips":["Set jpaCloseEntityManager=false for container-managed EntityManagers","Avoid double-closing sessions in custom interceptors","Let Spring/JTA own EM lifecycle in managed environments"],"tags":["jpa","entitymanager","lifecycle","activiti"],"backgroundTag":"invalid-state-transition","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}