hibernate/hibernate-orm · error · InstantiationException
Error instantiating class '{}' using default constructor: {}
Error message
Error instantiating class '{}' using default constructor: {} What it means
Injection-style dynamic instantiation first creates the target instance via its declared no-arg constructor (getDeclaredConstructor() + setAccessible + newInstance) before applying bean injections. If the class has no no-arg constructor, or it cannot be invoked (private constructor in a closed module, non-static inner class requiring an enclosing instance), the reflection exception is wrapped as InstantiationException("Error instantiating class '<class>' using default constructor: <message>").
Source
Thrown at hibernate-core/src/main/java/org/hibernate/sql/results/graph/instantiation/internal/DynamicInstantiationAssemblerInjectionImpl.java:97
}
@Override
public JavaType<T> getAssembledJavaType() {
return target;
}
@Override
@SuppressWarnings("unchecked")
public T assemble(RowProcessingState rowProcessingState) {
final T result;
try {
final var constructor = target.getJavaTypeClass().getDeclaredConstructor();
constructor.setAccessible( true );
result = constructor.newInstance();
}
catch ( NoSuchMethodException | IllegalAccessException | InvocationTargetException | InstantiationException
| java.lang.InstantiationException e ) {
throw new InstantiationException( "Error instantiating class '"
+ target.getTypeName() + "' using default constructor: " + e.getMessage(), e );
}
for ( var beanInjection : beanInjections ) {
final Object assembled = beanInjection.getValueAssembler().assemble( rowProcessingState );
beanInjection.getBeanInjector().inject( result, assembled );
}
return result;
}
@Override
public void resolveState(RowProcessingState rowProcessingState) {
for ( var beanInjection : beanInjections ) {
beanInjection.getValueAssembler().resolveState( rowProcessingState );
}
}
@Override
public <X> void forEachResultAssembler(BiConsumer<Initializer<?>, X> consumer, X arg) {View on GitHub (pinned to fad1729dce)
Solutions
- Add a public no-arg constructor to the target class (this path requires it), keeping setters/fields writable for the aliases.
- If you want construction control, define an explicit constructor matching the select items - Hibernate will use the constructor path instead of injection.
- For Kotlin, add a secondary constructor or apply the kotlin-noarg plugin for the DTO.
- Ensure the class is a top-level or public static nested class and its package is open to reflection when running modularized.
Example fix
// before
public class StatsDto {
public StatsDto(String region, Long total) { ... } // no default constructor
}
// after - keep the explicit ctor AND add the no-arg ctor for injection
public class StatsDto {
public StatsDto() { }
public StatsDto(String region, Long total) { ... }
} Defensive patterns
Strategy: validation
Validate before calling
// At startup, verify the injection target has an invokable no-arg constructor
Constructor<?> c;
try {
c = StatsDto.class.getDeclaredConstructor();
} catch (NoSuchMethodException e) {
throw new IllegalStateException("StatsDto needs a no-arg constructor for bean-injection instantiation", e);
}
if (!Modifier.isPublic(c.getModifiers()) && !c.trySetAccessible()) {
throw new IllegalStateException("no-arg constructor of StatsDto is not accessible");
} Type guard
// Reflective guard: type is usable for injection-style instantiation
static boolean hasUsableNoArgCtor(Class<?> dto) {
try {
Constructor<?> c = dto.getDeclaredConstructor();
return Modifier.isPublic(c.getModifiers()) || c.trySetAccessible();
} catch (NoSuchMethodException e) { return false; }
} Try / catch
try {
rows = q.getResultList();
} catch (org.hibernate.query.sqm.sql.internal.InstantiationException e) {
if (String.valueOf(e.getMessage()).contains("using default constructor")) {
// add a public no-arg constructor, or switch to an explicit constructor expression
}
} Prevention
- Every bean-injection DTO gets an explicit public no-arg constructor in addition to convenience constructors.
- For Kotlin DTOs, add a secondary no-arg constructor or apply the kotlin-noarg plugin.
- Prefer explicit constructor expressions when you want construction to fail fast at plan build, not per row.
When it happens
Trigger: `select new com.acme.Dto(...) ...` where the injection path was chosen (no matching all-args constructor) but Dto defines only parameterized constructors; a private no-arg constructor under JPMS where setAccessible fails; a non-static inner class as the target (its hidden constructor needs the outer instance).
Common situations: DTOs that 'grew' an all-args constructor so the implicit default constructor disappeared; immutable-style DTOs with only final-field constructors; Kotlin data classes without a no-arg secondary constructor; Java 9+ module access rules.
Related errors
- Error performing the dynamic instantiation
- Cannot set field '{}' to instantiate '{}'
- Error performing the dynamic instantiation
- Error instantiating class '{}'
- dynamic instantiation in a sub-query is unsupported
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/3c989a89c60e7661.
Report an issue: GitHub.