{"record":{"id":"93ba28ffe9cd3673","repo":"hibernate/hibernate-orm","slug":"extendedbeanmanager-lifecyclelistener-callback-not","errorCode":null,"errorMessage":"ExtendedBeanManager.LifecycleListener callback not yet called: CDI not (yet) usable","messagePattern":"ExtendedBeanManager\\.LifecycleListener callback not yet called: CDI not \\(yet\\) usable","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/resource/beans/container/internal/CdiBeanContainerExtendedAccessImpl.java","lineNumber":81,"sourceCode":"\t\t}\n\t}\n\n\t@Override\n\tpublic void beanManagerInitialized(BeanManager beanManager) {\n\t\tthis.usableBeanManager = beanManager;\n\t\tforEachBean( ContainedBeanImplementor::initialize );\n\t}\n\n\t@Override\n\tpublic void beforeBeanManagerDestroyed(BeanManager beanManager) {\n\t\tstop();\n\t\tthis.usableBeanManager = null;\n\t}\n\n\t@Override\n\tpublic BeanManager getUsableBeanManager() {\n\t\tif ( usableBeanManager == null ) {\n\t\t\tthrow new IllegalStateException( \"ExtendedBeanManager.LifecycleListener callback not yet called: CDI not (yet) usable\" );\n\t\t}\n\t\treturn usableBeanManager;\n\t}\n\n\t@Internal\n\tpublic BeanManager getBeanManager() {\n\t\treturn usableBeanManager;\n\t}\n\n\tprivate class BeanImpl<B> implements ContainedBeanImplementor<B> {\n\t\tprivate final Class<B> beanType;\n\t\tprivate final BeanLifecycleStrategy lifecycleStrategy;\n\t\tprivate final BeanInstanceProducer fallbackProducer;\n\n\t\tprivate ContainedBeanImplementor<B> delegateContainedBean;\n\n\t\tprivate BeanImpl(\n\t\t\t\tClass<B> beanType,","sourceCodeStart":63,"sourceCodeEnd":99,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/resource/beans/container/internal/CdiBeanContainerExtendedAccessImpl.java#L63-L99","documentation":"CdiBeanContainerExtendedAccessImpl defers CDI usage to the ExtendedBeanManager lifecycle: usableBeanManager is set only after the container fires the bean-manager-initialized callback and is nulled in beforeBeanManagerDestroyed. getUsableBeanManager() throws IllegalStateException when Hibernate needs a bean before that callback has fired, or after CDI has been torn down.","triggerScenarios":"Hibernate resolves a CDI-managed bean (entity listener, converter, or any BeanContainer consumer) while usableBeanManager is null: during EntityManagerFactory/SessionFactory bootstrap before the CDI container finished startup, or during shutdown when the SessionFactory still resolves beans after CDI was destroyed.","commonSituations":"SE apps passing Weld's ExtendedBeanManager; app-server or Quarkus-style boot where EMF creation races CDI initialization; tests that build the EMF before the CDI container starts; shutdown ordering where the CDI container closes before the EntityManagerFactory.","solutions":["Build the EntityManagerFactory only after CDI is fully started (e.g. in an AfterDeploymentValidation observer).","In plain Java SE, pass the ready BeanManager via 'jakarta.persistence.bean.manager' instead of an ExtendedBeanManager.","Fix shutdown ordering: close the EntityManagerFactory before stopping the CDI container.","Ensure exactly one lifecycle observer is registered so the initialized callback actually reaches Hibernate."],"exampleFix":"// before\nMap<String, Object> props = Map.of(\"jakarta.persistence.bean.manager\", extendedBeanManager);\nEntityManagerFactory emf = Persistence.createEntityManagerFactory(\"pu\", props);\n// created too early: callback not yet fired -> IllegalStateException\n\n// after\nvoid onCdiReady(@Observes AfterDeploymentValidation adv, BeanManager bm) {\n    this.emf = Persistence.createEntityManagerFactory(\n        \"pu\", Map.of(\"jakarta.persistence.bean.manager\", bm));\n}","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"// defer EMF creation until CDI signals readiness; retry bean-dependent boot once started\nvoid init() {\n    if (!cdiStarted) { pendingBoot = this::init; return; }\n    try {\n        this.emf = Persistence.createEntityManagerFactory(\"pu\", props);\n    } catch (IllegalStateException e) {\n        // 'ExtendedBeanManager.LifecycleListener callback not yet called'\n        throw new BootOrderException(\"Build the EMF after the CDI container started\", e);\n    }\n}","preventionTips":["Create the EntityManagerFactory inside an AfterDeploymentValidation observer.","Close the EntityManagerFactory before shutting down the CDI container.","In Java SE, prefer passing a fully started BeanManager instead of an ExtendedBeanManager."],"tags":["hibernate","cdi","bean-manager","bootstrap","weld"],"backgroundTag":"cdi-bean-manager-not-ready","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}