{"record":{"id":"d31c8ea00bf09374","repo":"quarkusio/quarkus","slug":"persistence-unit-is-closed","errorCode":null,"errorMessage":"Persistence unit is closed","messagePattern":"Persistence unit is closed","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"extensions/hibernate-orm/runtime/src/main/java/io/quarkus/hibernate/orm/runtime/JPAConfig.java","lineNumber":175,"sourceCode":"    }\n\n    static final class LazyPersistenceUnit {\n\n        private final String name;\n        private final boolean isReactive;\n        private volatile EntityManagerFactory value;\n        private volatile boolean closed = false;\n\n        LazyPersistenceUnit(String name, boolean isReactive) {\n            this.name = name;\n            this.isReactive = isReactive;\n        }\n\n        EntityManagerFactory get() {\n            if (value == null) {\n                synchronized (this) {\n                    if (closed) {\n                        throw new IllegalStateException(\"Persistence unit is closed\");\n                    }\n                    if (value == null) {\n                        value = Persistence.createEntityManagerFactory(name,\n                                Collections.singletonMap(IS_REACTIVE_KEY, isReactive));\n                    }\n                }\n            }\n            return value;\n        }\n\n        public synchronized void close() {\n            closed = true;\n            EntityManagerFactory emf = this.value;\n            this.value = null;\n            if (emf != null) {\n                emf.close();\n            }\n        }","sourceCodeStart":157,"sourceCodeEnd":193,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/hibernate-orm/runtime/src/main/java/io/quarkus/hibernate/orm/runtime/JPAConfig.java#L157-L193","documentation":"Thrown by JPAConfig's lazy EntityManagerFactory holder after the persistence unit has been explicitly closed via JPAConfig.stop(). Once closed, the holder refuses to re-bootstrap the EMF, signaling the application is shutting down or the PU was torn down. It guards against recreating EMFs during shutdown (e.g. from a shutdown hook, async task, or scheduled job still running).","triggerScenarios":"Code calls getEntityManagerFactory()/createEntityManager after the application has begun shutdown (JPAConfig.stop invoked); a background thread, timer, or Dev UI request races application termination; closing and then re-accessing the PU in a test.","commonSituations":"Quartz/Scheduled jobs firing during graceful shutdown; long-running streams writing to the DB while Quarkus stops; tests that stop JPAConfig mid-test then keep using entities.","solutions":["Stop using the persistence unit after shutdown begins; shut down your executors/schedulers before Quarkus terminates.","Check application state: if this happens at shutdown, treat it as expected and drain tasks gracefully.","If it happens mid-run, audit for manual calls to JPAConfig.stop()/close in your code or tests."],"exampleFix":"// before\nexecutor.submit(() -> emf.createEntityManager()); // may run after shutdown\n// after\nexecutor.shutdown();\nexecutor.awaitTermination(30, TimeUnit.SECONDS); // drain before PU closes","handlingStrategy":"try-catch","validationCode":"// Check quarkus runtime status before submitting background JPA work\nif (!Quarkus.isStarted() || Quarkus.isStopping()) {\n    return; // skip DB work during shutdown\n}","typeGuard":null,"tryCatchPattern":"try {\n    EntityManager em = emf.createEntityManager();\n    // ...\n} catch (IllegalStateException e) {\n    if (\"Persistence unit is closed\".equals(e.getMessage())) {\n        log.info(\"Skipping task: application is shutting down\");\n    } else { throw e; }\n}","preventionTips":["Drain executors and schedulers before shutdown (graceful lifecycle) using @Lifespan or runWhenShutdown handlers","Avoid firing new DB tasks from shutdown hooks","Make scheduled jobs check shutdown state before touching JPA"],"tags":["jpa","lifecycle","shutdown","hibernate-orm","quarkus"],"backgroundTag":"persistence-unit-closed","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}