{"record":{"id":"5da953a9044411e4","repo":"hibernate/hibernate-orm","slug":"registered-strategy-s-is-not-a-subtype-of-s","errorCode":null,"errorMessage":"Registered strategy [%s] is not a subtype of [%s]","messagePattern":"Registered strategy \\[(.+?)\\] is not a subtype of \\[(.+?)\\]","errorType":"exception","errorClass":"StrategySelectionException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/boot/registry/selector/internal/StrategySelectorImpl.java","lineNumber":140,"sourceCode":"\t\t\t\tcreator\n\t\t);\n\t}\n\n\t@Override\n\tpublic <T> Collection<Class<? extends T>> getRegisteredStrategyImplementors(Class<T> strategy) {\n\t\tfinal var lazyServiceResolver = lazyStrategyImplementorByStrategyMap.get( strategy );\n\t\tif ( lazyServiceResolver != null ) {\n\t\t\tthrow new StrategySelectionException( \"Can't use this method on for strategy types which are embedded in the core library\" );\n\t\t}\n\t\tfinal var registrations = namedStrategyImplementorByStrategyMap.get( strategy );\n\t\tif ( registrations == null ) {\n\t\t\treturn emptySet();\n\t\t}\n\t\telse {\n\t\t\tfinal Set<Class<? extends T>> implementors = new HashSet<>();\n\t\t\tfor ( var registration : registrations.values() ) {\n\t\t\t\tif ( !strategy.isAssignableFrom( registration ) ) {\n\t\t\t\t\tthrow new StrategySelectionException(\n\t\t\t\t\t\t\tString.format(\n\t\t\t\t\t\t\t\t\t\"Registered strategy [%s] is not a subtype of [%s]\",\n\t\t\t\t\t\t\t\t\tregistration.getName(),\n\t\t\t\t\t\t\t\t\tstrategy.getName()\n\t\t\t\t\t\t\t)\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\timplementors.add( registration.asSubclass( strategy ) );\n\t\t\t}\n\t\t\treturn implementors;\n\t\t}\n\t}\n\n\t@SuppressWarnings(\"unchecked\")\n\t@Override\n\tpublic <T> T resolveStrategy(\n\t\t\tClass<T> strategy,\n\t\t\tObject strategyReference,","sourceCodeStart":122,"sourceCodeEnd":158,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/boot/registry/selector/internal/StrategySelectorImpl.java#L122-L158","documentation":"While collecting a strategy's registered implementors, each entry in the name-to-implementor map is re-checked for assignability; a stored class that is not a subtype of the strategy throws StrategySelectionException naming both classes. Registrations are validated when added, so surviving to this check indicates corrupted registration state: the same class loaded by two different classloaders, or entries inserted under a wrong key via the deprecated registerStrategyImplementor.","triggerScenarios":"Calling getRegisteredStrategyImplementors on a registry whose registration map holds mismatched entries - typically duplicated Hibernate jars across parent/child classloaders in an app server, or unchecked use of the deprecated registerStrategyImplementor with a non-subtype class.","commonSituations":"Deploying hibernate-core both in the server's lib directory and inside the WAR; shaded/fat jars embedding Hibernate classes alongside the real dependency; mixed Hibernate versions on one classpath.","solutions":["Deduplicate hibernate-core on the classpath (mvn dependency:tree / gradle dependencies; check server modules vs deployment)","Stop using deprecated registerStrategyImplementor with unchecked types; re-register through a typed StrategyRegistration","Restart with a single, consistent Hibernate version across all modules"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// Consistency check at startup: one classloader, one Hibernate version\nClass<?> h1 = Class.forName(\"org.hibernate.Version\", false, getClass().getClassLoader());\nif (h1.getProtectionDomain().getCodeSource() == null) {\n    log.warn(\"Hibernate loaded from unknown source - check for shaded jars\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    return strategySelector.getRegisteredStrategyImplementors(strategy);\n} catch (StrategySelectionException e) {\n    if (e.getMessage().contains(\"is not a subtype of\")) {\n        // registration map corrupted by duplicate jars/classloaders - audit the classpath\n        log.error(\"Duplicate Hibernate artifacts detected; run dependency:tree\", e);\n    }\n    throw e;\n}","preventionTips":["Keep exactly one copy of hibernate-core on the classpath (server lib XOR deployment, never both)","Audit fat/uber jars for embedded org.hibernate classes","Avoid the deprecated untyped registerStrategyImplementor in favor of typed StrategyRegistrations"],"tags":["hibernate","strategy","classloading","duplicate-dependency"],"backgroundTag":"strategy-registration-mismatch","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}