hibernate/hibernate-orm · error · StrategySelectionException
Registered strategy [%s] is not a subtype of [%s]
Error message
Registered strategy [%s] is not a subtype of [%s]
What it means
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.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/boot/registry/selector/internal/StrategySelectorImpl.java:140
creator
);
}
@Override
public <T> Collection<Class<? extends T>> getRegisteredStrategyImplementors(Class<T> strategy) {
final var lazyServiceResolver = lazyStrategyImplementorByStrategyMap.get( strategy );
if ( lazyServiceResolver != null ) {
throw new StrategySelectionException( "Can't use this method on for strategy types which are embedded in the core library" );
}
final var registrations = namedStrategyImplementorByStrategyMap.get( strategy );
if ( registrations == null ) {
return emptySet();
}
else {
final Set<Class<? extends T>> implementors = new HashSet<>();
for ( var registration : registrations.values() ) {
if ( !strategy.isAssignableFrom( registration ) ) {
throw new StrategySelectionException(
String.format(
"Registered strategy [%s] is not a subtype of [%s]",
registration.getName(),
strategy.getName()
)
);
}
implementors.add( registration.asSubclass( strategy ) );
}
return implementors;
}
}
@SuppressWarnings("unchecked")
@Override
public <T> T resolveStrategy(
Class<T> strategy,
Object strategyReference,View on GitHub (pinned to fad1729dce)
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
Defensive patterns
Strategy: try-catch
Validate before calling
// Consistency check at startup: one classloader, one Hibernate version
Class<?> h1 = Class.forName("org.hibernate.Version", false, getClass().getClassLoader());
if (h1.getProtectionDomain().getCodeSource() == null) {
log.warn("Hibernate loaded from unknown source - check for shaded jars");
} Try / catch
try {
return strategySelector.getRegisteredStrategyImplementors(strategy);
} catch (StrategySelectionException e) {
if (e.getMessage().contains("is not a subtype of")) {
// registration map corrupted by duplicate jars/classloaders - audit the classpath
log.error("Duplicate Hibernate artifacts detected; run dependency:tree", e);
}
throw e;
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Unable to resolve name [{}] as strategy [{}]
- Detected a second LazyServiceResolver replacing an existing
- Name of class to load cannot be null
- %s
- Could not instantiate named strategy class [{}]
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/5da953a9044411e4.
Report an issue: GitHub.