hibernate/hibernate-orm · error · StrategySelectionException
Could not instantiate named strategy class [{}]
Error message
Could not instantiate named strategy class [{}] What it means
When hibernate.query.mutation_strategy names a custom SqmMultiTableMutationStrategy class, SessionFactoryOptionsBuilder tries to instantiate it via its Dialect-accepting constructor or its no-arg constructor. If the chosen constructor exists but invocation fails (constructor body throws, class is abstract, or access is denied), a StrategySelectionException wrapping the cause is thrown during SessionFactory bootstrap.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/boot/internal/SessionFactoryOptionsBuilder.java:728
}
else if ( hasStrategyConstructorSignature( parameterTypes ) ) {
entityBasedConstructor = (Constructor<SqmMultiTableMutationStrategy>) declaredConstructor;
}
}
if ( entityBasedConstructor == null ) {
try {
if ( dialectConstructor != null ) {
return dialectConstructor.newInstance(
serviceRegistry.requireService( JdbcServices.class ).getDialect()
);
}
else if ( emptyConstructor != null ) {
return emptyConstructor.newInstance();
}
}
catch (Exception e) {
throw new StrategySelectionException(
"Could not instantiate named strategy class [" + strategyClass.getName() + "]",
e
);
}
throw new IllegalArgumentException( "Cannot instantiate the class [" + strategyClass.getName()
+ "] because it does not have a constructor that accepts a dialect or an empty constructor" );
}
else {
return null;
}
}
);
}
@SuppressWarnings("unchecked")
@Nullable
private Constructor<SqmMultiTableMutationStrategy> resolveSqmMutationStrategyConstructor(
String strategyName,View on GitHub (pinned to fad1729dce)
Solutions
- Read the nested cause of the StrategySelectionException — InvocationTargetException.getCause() points at the real failure inside your constructor
- Make the strategy class and its Dialect/no-arg constructor public
- Move heavy initialization out of the constructor; defer to first use when the runtime context is available
- If the strategy needs per-entity context, provide a public (EntityMappingType, RuntimeModelCreationContext) constructor instead
Example fix
// before:
public MyMutationStrategy(Dialect dialect) {
this.schema = requireGlobalConfig().getSchema(); // throws NPE at bootstrap
}
// after:
public MyMutationStrategy(Dialect dialect) {
this.dialect = dialect; // defer schema resolution to first use
}
public String schema() { return GlobalConfigHolder.schema(); } Defensive patterns
Strategy: try-catch
Validate before calling
// verify the strategy's constructor shape before boot
static boolean hasSupportedStrategyCtor(Class<?> c) {
return Arrays.stream(c.getDeclaredConstructors()).anyMatch(ctor -> {
Class<?>[] p = ctor.getParameterTypes();
return java.lang.reflect.Modifier.isPublic(ctor.getModifiers())
&& (p.length == 0 || (p.length == 1 && Dialect.class.isAssignableFrom(p[0]))
|| (p.length == 2 && p[0] == EntityMappingType.class
&& p[1] == RuntimeModelCreationContext.class));
});
} Try / catch
try {
sessionFactory = metadata.buildSessionFactory();
} catch (StrategySelectionException e) {
if (e.getMessage() != null && e.getMessage().contains("hibernate.query.mutation_strategy class")) {
Throwable root = e.getCause();
while (root.getCause() != null) root = root.getCause();
log.error("Custom mutation strategy constructor failed: {}", root, e);
}
throw e;
} Prevention
- Keep strategy constructors trivial — no service lookups, no dialect feature calls
- Write a dedicated bootstrap test that builds the factory with the custom strategy on all target dialects
- Log the registered strategy class at startup so failures are traceable to config
When it happens
Trigger: Setting hibernate.query.mutation_strategy=com.acme.MyStrategy where MyStrategy has a Dialect or no-arg constructor whose body throws (commonly NPE from missing services), or the class/constructor is not accessible to reflection.
Common situations: Custom strategy assumes a connection or configuration source that is null at bootstrap time; constructor performs dialect feature checks that fail on unexpected dialects; strategy class made package-private or constructor made private after refactoring; upgrading Hibernate changes constructor invocation order.
Related errors
- Could not instantiate event listener '{}'
- Unable to instantiate StatementObserver - {}
- Cannot instantiate the class [{}] because it does not have a
- Unable to create AttributeConverter instance
- Could not instantiate named strategy class [%s]
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/8827e448111103e9.
Report an issue: GitHub.