{"record":{"id":"180bb0db29806af7","repo":"hibernate/hibernate-orm","slug":"dependency-dependentservicerole-declared-by-s","errorCode":null,"errorMessage":"Dependency [${dependentServiceRole}] declared by service [${service}] not found","messagePattern":"Dependency \\[(.+?)\\] declared by service \\[(.+?)\\] not found","errorType":"exception","errorClass":"ServiceDependencyException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/service/internal/AbstractServiceRegistryImpl.java","lineNumber":319,"sourceCode":"\tprivate <T extends Service> void processInjection(\n\t\t\t@Nonnull T service,\n\t\t\t@Nonnull Method injectionMethod,\n\t\t\t@Nonnull InjectService injectService) {\n\t\tinjectDependentService( service, injectionMethod, injectService,\n\t\t\t\tdependentServiceRole( injectionMethod, injectService ) );\n\t}\n\n\tprivate <T extends Service> void injectDependentService(\n\t\t\t@Nonnull T service,\n\t\t\t@Nonnull Method injectionMethod,\n\t\t\t@Nonnull InjectService injectService,\n\t\t\t@Nonnull Class<? extends Service> dependentServiceRole) {\n\t\t// todo : because of the use of proxies, this is no longer returning null here...\n\n\t\tfinal var dependantService = getService( dependentServiceRole );\n\t\tif ( dependantService == null ) {\n\t\t\tif ( injectService.required() ) {\n\t\t\t\tthrow new ServiceDependencyException(\n\t\t\t\t\t\t\"Dependency [\" + dependentServiceRole + \"] declared by service [\" + service + \"] not found\"\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t\telse {\n\t\t\ttry {\n\t\t\t\tinjectionMethod.invoke( service, dependantService );\n\t\t\t}\n\t\t\tcatch ( Exception e ) {\n\t\t\t\tthrow new ServiceDependencyException( \"Cannot inject dependency service\", e );\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate static Class<? extends Service> dependentServiceRole(\n\t\t\t@Nonnull Method injectionMethod,\n\t\t\t@Nonnull InjectService injectService) {\n\t\tfinal var parameterTypes = injectionMethod.getParameterTypes();","sourceCodeStart":301,"sourceCodeEnd":337,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/service/internal/AbstractServiceRegistryImpl.java#L301-L337","documentation":"While wiring a service, Hibernate reflectively invokes methods annotated with @InjectService. When the dependent role cannot be resolved (getService returned null) and the annotation declares required = true (the default), ServiceDependencyException is thrown naming both the missing dependency role and the dependent service. The registry cannot finish initializing that service.","triggerScenarios":"A custom or internal service declaring a required @InjectService dependency on a role that is not registered in the same registry hierarchy; init-order or hierarchy problems where the dependency lives in a sibling registry; role class renamed between Hibernate versions.","commonSituations":"Custom services depending on optional Hibernate services that were never contributed; test registries built with a subset of services; integrations written against one Hibernate version running against another where the dependency role moved.","solutions":["Register the missing dependency role (initiator/contributor/addService) before the dependent service initializes","If the dependency is genuinely optional, annotate the setter with @InjectService(required = false) and null-check inside","Verify the serviceRole attribute and the setter parameter type match the registered role exactly","For tests, build the registry with the real services the code-under-test depends on instead of a stripped-down one"],"exampleFix":"// before\n@InjectService // required=true by default, role not registered\npublic void setMetrics(MetricsService metrics) { this.metrics = metrics; }\n\n// after\n@InjectService(required = false)\npublic void setMetrics(MetricsService metrics) { this.metrics = metrics; }\n// ...and at use site:\nif (metrics != null) metrics.record();","handlingStrategy":"validation","validationCode":"// before initializing the dependent service, confirm the role is bound\nif (registry.getService(TheDependency.class) == null) {\n    builder.addService(TheDependency.class, new TheDependencyImpl());\n}","typeGuard":null,"tryCatchPattern":"try {\n    registry.requireService(MyDependentService.class);\n}\ncatch (ServiceDependencyException e) {\n    // message names the missing role; register it and retry the lookup\n    LOG.error(\"missing service dependency: {}\", e.getMessage());\n}","preventionTips":["Mark genuinely optional dependencies @InjectService(required = false)","Register all dependencies before the dependent service initializes (contributors do this deterministically)","Smoke-test full registry construction in CI so missing dependencies fail the build"],"tags":["service-registry","dependency-injection","bootstrap"],"backgroundTag":"missing-service-dependency","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}