{"record":{"id":"d186f6c2a8bdfb64","repo":"hibernate/hibernate-orm","slug":"entitymanagerfactory-is-closed","errorCode":null,"errorMessage":"EntityManagerFactory is closed","messagePattern":"EntityManagerFactory is closed","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/internal/SessionFactoryImpl.java","lineNumber":780,"sourceCode":"\tpublic StatelessSession openStatelessSession(@Nonnull Connection connection) {\n\t\treturn withStatelessOptions().connection( connection ).openStatelessSession();\n\t}\n\n\t@Override\n\tpublic void addObserver(@Nonnull SessionFactoryObserver observer) {\n\t\tobserverChain.addObserver( observer );\n\t}\n\n\t@Override\n\t@Nonnull\n\tpublic Map<String, Object> getProperties() {\n\t\tvalidateNotClosed();\n\t\treturn settings;\n\t}\n\n\tprotected void validateNotClosed() {\n\t\tif ( status == Status.CLOSED ) {\n\t\t\tthrow new IllegalStateException( \"EntityManagerFactory is closed\" );\n\t\t}\n\t}\n\n\t@Override\n\tpublic String getUuid() {\n\t\treturn uuid;\n\t}\n\n\t@Override\n\tpublic String getName() {\n\t\treturn name;\n\t}\n\n\t@Override\n\tpublic String getJndiName() {\n\t\treturn jndiName;\n\t}\n","sourceCodeStart":762,"sourceCodeEnd":798,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/internal/SessionFactoryImpl.java#L762-L798","documentation":"Most SessionFactory/EntityManagerFactory accessors (getProperties(), metamodel access, createEntityManager()) start with validateNotClosed(), which throws IllegalStateException once the factory's status is CLOSED. Hibernate intentionally fails fast instead of serving stale data from a shut-down factory. The factory is a heavyweight object whose services are released by close().","triggerScenarios":"Calling emf.getProperties(), emf.createEntityManager(), or any other guarded method after emf.close() (or Spring container shutdown closing the shared EMF). Typical in @PreDestroy ordering bugs, static EMF holders, or code that caches the EMF across application restarts in the same JVM.","commonSituations":"Spring Boot devtools restart or context refresh closing the EMF while a background thread still uses it; shutdown hooks that close the factory before other hooks read settings; test classes sharing a container-managed EMF that was closed by a previous test suite; fat-client apps that rebuild the factory but keep old references.","solutions":["Guard every access with if (emf != null && emf.isOpen()) before using the factory","Fix the lifecycle ordering: close the EMF last, after all components that use it (check @PreDestroy / shutdown-hook order, Spring dependsOn)","Cache any settings you need after close (e.g. copy getProperties() into your own map during startup) instead of reading them later","In tests, use a shared EMF per suite or recreate it in @BeforeAll/@AfterAll so no test touches a closed factory"],"exampleFix":"// before\npublic Map<String, Object> config() {\n    return emf.getProperties(); // throws if container already closed the EMF\n}\n\n// after\npublic Map<String, Object> config() {\n    if (emf == null || !emf.isOpen()) {\n        throw new IllegalStateException(\"application context already shut down\");\n    }\n    return emf.getProperties();\n}","handlingStrategy":"validation","validationCode":"public Map<String, Object> safeProperties(EntityManagerFactory emf) {\n    if (!emf.isOpen()) {\n        throw new IllegalStateException(\"EntityManagerFactory is closed; cannot read properties\");\n    }\n    return emf.getProperties();\n}","typeGuard":null,"tryCatchPattern":"try {\n    return emf.getProperties();\n} catch (IllegalStateException e) {\n    // factory closed — fall back to a snapshot captured at startup\n    return startupPropertySnapshot;\n}","preventionTips":["Copy any settings you need for shutdown/reporting into your own structures during startup","Give the EMF a single owner and close it last in the shutdown order (Spring: let the container own it)","Guard all long-lived references with isOpen() before use, especially in background threads and shutdown hooks"],"tags":["hibernate","jpa","lifecycle","closed-resource","entity-manager-factory"],"backgroundTag":"use-after-close","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}