hibernate/hibernate-orm · error · IllegalArgumentException
Cannot instantiate the class [{}] because it does not have a
Error message
Cannot instantiate the class [{}] because it does not have a constructor that accepts a dialect or an empty constructor What it means
For a custom class named by hibernate.query.mutation_strategy, SessionFactoryOptionsBuilder scans declared constructors looking for one of two supported shapes: a single-argument Dialect constructor, or a no-arg constructor (a (EntityMappingType, RuntimeModelCreationContext) constructor defers instantiation per entity). If none of these exists, it throws IllegalArgumentException explaining the class cannot be instantiated. This is a constructor-shape mismatch, not an invocation failure.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/boot/internal/SessionFactoryOptionsBuilder.java:733
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,
StrategySelector strategySelector) {
if ( strategyName != null ) {
final var strategyClass =
strategySelector.selectStrategyImplementor( SqmMultiTableMutationStrategy.class, strategyName );
for ( var declaredConstructor : strategyClass.getDeclaredConstructors() ) {View on GitHub (pinned to fad1729dce)
Solutions
- Add a public constructor taking exactly one org.hibernate.dialect.Dialect argument
- Or add a public no-argument constructor
- Or provide a public constructor with exactly (EntityMappingType, RuntimeModelCreationContext) for per-entity strategies
- Keep at least one of the supported constructors when refactoring
Example fix
// before:
public MyMutationStrategy(ConnectionProvider cp) { ... } // only constructor
// after:
public MyMutationStrategy(Dialect dialect) {
this.dialect = dialect;
this.cp = null; // resolve lazily if needed
}
public MyMutationStrategy(ConnectionProvider cp) { ... } // keep for your own use Defensive patterns
Strategy: validation
Validate before calling
// fail fast if the custom strategy lacks a supported constructor
Class<?> strategy = Class.forName(props.getProperty("hibernate.query.mutation_strategy"));
boolean ok = Arrays.stream(strategy.getDeclaredConstructors()).anyMatch(c -> {
Class<?>[] p = c.getParameterTypes();
return p.length == 0 || Dialect.class == p[0]
|| (p.length == 2 && p[0] == EntityMappingType.class && p[1] == RuntimeModelCreationContext.class);
});
if (!ok) throw new IllegalStateException("Strategy needs (Dialect), (), or (EntityMappingType, RuntimeModelCreationContext) ctor"); Type guard
static boolean hasHibernateStrategyConstructor(Class<?> c) {
return Arrays.stream(c.getDeclaredConstructors()).anyMatch(ctor -> {
Class<?>[] p = ctor.getParameterTypes();
return 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 (IllegalArgumentException e) {
if (e.getMessage() != null && e.getMessage().contains("does not have a constructor")) {
// add a (Dialect) or no-arg constructor to the named class, then rebuild
}
throw e;
} Prevention
- Treat the supported constructor shapes ((Dialect), (), (EntityMappingType, RuntimeModelCreationContext)) as part of the strategy SPI contract and document them in the class javadoc
- Add an architecture/reflect test asserting the strategy keeps a supported constructor
- Prefer the Dialect constructor so strategies can adapt per database
When it happens
Trigger: Registering a SqmMultiTableMutationStrategy implementation that only offers constructors with other parameter lists, e.g. MyStrategy(ConnectionProvider), MyStrategy(int), or MyStrategy(Dialect, Settings).
Common situations: Writing a custom strategy from scratch without matching Hibernate's expected constructor contract; refactoring a working strategy's constructor signature; strategy originally built for constructor injection frameworks.
Related errors
- Could not instantiate named strategy class [{}]
- Unable to resolve name [{}] as strategy [{}]
- Default resolver threw exception
- Could not instantiate named strategy class [%s]
- The {storageEngine} storage engine is not supported
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/0c3ce34d840946a2.
Report an issue: GitHub.