{"record":{"id":"43b67dce619d4a49","repo":"hibernate/hibernate-orm","slug":"no-child-serviceregistry-registrations-found","errorCode":null,"errorMessage":"No child ServiceRegistry registrations found","messagePattern":"No child ServiceRegistry registrations found","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/boot/registry/internal/BootstrapServiceRegistryImpl.java","lineNumber":281,"sourceCode":"\t\t\t\tSERVICE_LOGGER.unableToStopService( binding.getServiceRole().getName(), e );\n\t\t\t}\n\t\t}\n\t}\n\n\t@Override\n\tpublic synchronized void registerChild(@Nonnull ServiceRegistryImplementor child) {\n\t\tif ( childRegistries == null ) {\n\t\t\tchildRegistries = new HashSet<>();\n\t\t}\n\t\tif ( !childRegistries.add( child ) ) {\n\t\t\tSERVICE_LOGGER.childAlreadyRegistered( child );\n\t\t}\n\t}\n\n\t@Override\n\tpublic synchronized void deRegisterChild(@Nonnull ServiceRegistryImplementor child) {\n\t\tif ( childRegistries == null ) {\n\t\t\tthrow new IllegalStateException( \"No child ServiceRegistry registrations found\" );\n\t\t}\n\t\tchildRegistries.remove( child );\n\t\tif ( childRegistries.isEmpty() ) {\n\t\t\tif ( autoCloseRegistry ) {\n\t\t\t\tSERVICE_LOGGER.destroyingBootstrapRegistry();\n\t\t\t\tdestroy();\n\t\t\t}\n\t\t\telse {\n\t\t\t\tSERVICE_LOGGER.skippingBootstrapRegistryDestruction();\n\t\t\t}\n\t\t}\n\t}\n\n\t@Override\n\tpublic <T extends Service> T fromRegistryOrChildren(@Nonnull Class<T> serviceRole) {\n\t\treturn AbstractServiceRegistryImpl.fromRegistryOrChildren( serviceRole, this, childRegistries );\n\t}\n}","sourceCodeStart":263,"sourceCodeEnd":299,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/boot/registry/internal/BootstrapServiceRegistryImpl.java#L263-L299","documentation":"BootstrapServiceRegistryImpl lazily creates its child-registry set on the first registerChild() call; deRegisterChild() throws IllegalStateException when that set is still null - i.e., a child is being deregistered before any child was ever registered, or after the registry was already destroyed and cleared. In practice StandardServiceRegistry.close() deregisters itself from its parent bootstrap registry, so this signals out-of-order teardown.","triggerScenarios":"Closing a StandardServiceRegistry after its parent BootstrapServiceRegistry was already destroyed (child set gone), or calling deRegisterChild directly on a bootstrap registry that never registered children; also double-close sequences where the registry already destroyed itself after the last child deregistered (autoCloseRegistry).","commonSituations":"Double-close of SessionFactory/registry chains; tests that manually destroy the bootstrap registry and then close child factories; framework restart code closing registries in the wrong order.","solutions":["Close exactly once in the correct order: SessionFactory, then its StandardServiceRegistry, then let the bootstrap registry auto-close when the last child deregisters","Guard teardown with isActive() checks and avoid manually destroying a bootstrap registry that still has live children","In tests, use try-with-resources or lifecycle extensions that own the whole chain"],"exampleFix":"// before\nbootstrapRegistry.destroy();          // destroys parent first\nstandardRegistry.close();              // -> IllegalStateException in deRegisterChild\n\n// after\nstandardRegistry.close();              // child first; bootstrap auto-closes when empty\n// no manual bootstrapRegistry.destroy() needed","handlingStrategy":"validation","validationCode":"// Close-order guard: only close a child registry while the parent is still active\nif (standardRegistry.isActive() && bootstrapRegistry.isActive()) {\n    standardRegistry.close(); // deregisters from bootstrap; bootstrap auto-closes when empty\n}","typeGuard":null,"tryCatchPattern":"try {\n    standardRegistry.close();\n} catch (IllegalStateException e) {\n    if (e.getMessage().contains(\"No child ServiceRegistry registrations\")) {\n        // already deregistered/destroyed: nothing left to do, ignore\n    } else {\n        throw e;\n    }\n}","preventionTips":["Close the chain in order exactly once: SessionFactory, then StandardServiceRegistry; let bootstrap auto-close","Never destroy a BootstrapServiceRegistry manually while children are alive","Use try-with-resources or framework-managed lifecycle beans for registries in tests"],"tags":["hibernate","service-registry","lifecycle","shutdown","double-close"],"backgroundTag":"invalid-lifecycle-transition","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}