hibernate/hibernate-orm · error · InstantiationException
Error instantiating class '{}'
Error message
Error instantiating class '{}' What it means
DynamicInstantiationAssemblerConstructorImpl.assemble() gathers all constructor arguments from the row and calls Constructor.newInstance(args). If the constructor itself throws, the InvocationTargetException is unwrapped and rethrown as InstantiationException("Error instantiating class '<class>'") with your constructor's exception as the cause. The query, argument binding and reflection all worked - your code inside the DTO constructor failed.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/sql/results/graph/instantiation/internal/DynamicInstantiationAssemblerConstructorImpl.java:52
@Override
public JavaType<R> getAssembledJavaType() {
return resultType;
}
@Override
public R assemble(RowProcessingState rowProcessingState) {
final int numberOfArgs = argumentReaders.size();
final var args = new Object[ numberOfArgs ];
for ( int i = 0; i < numberOfArgs; i++ ) {
args[i] = argumentReaders.get( i ).assemble( rowProcessingState );
}
try {
return targetConstructor.newInstance( args );
}
catch (InvocationTargetException e) {
throw new InstantiationException( "Error instantiating class '"
+ targetConstructor.getDeclaringClass().getName() + "'", e.getCause() );
}
catch (Exception e) {
throw new InstantiationException( "Error instantiating class '"
+ targetConstructor.getDeclaringClass().getName() + "'", e );
}
}
@Override
public void resolveState(RowProcessingState rowProcessingState) {
for ( var argumentReader : argumentReaders ) {
argumentReader.resolveState( rowProcessingState );
}
}
@Override
public <X> void forEachResultAssembler(BiConsumer<Initializer<?>, X> consumer, X arg) {
for ( var argumentReader : argumentReaders ) {View on GitHub (pinned to fad1729dce)
Solutions
- Read the cause exception and its stack trace - it identifies the failing line inside your constructor.
- Make the constructor null-safe: accept object/wrapper types and handle null before unboxing or parsing.
- Keep DTO constructors trivial (pure assignment); do normalization/derivation in factory methods or after the query returns.
- Add an integration test running the query against data including null columns and empty tables.
Example fix
// before
public SalesDto(Long id, double total) { // unboxing NPE when sum(amount) is null
this.ratio = total / base;
}
// after
public SalesDto(Long id, Double total) {
this.ratio = total == null ? 0d : total / base;
} Defensive patterns
Strategy: try-catch
Validate before calling
// Prove the constructor is null-safe before using it in select new
Constructor<SalesDto> ctor = SalesDto.class.getConstructor(Long.class, Double.class);
try {
ctor.newInstance(null, null); // exactly what an empty result set can produce
} catch (InvocationTargetException e) {
throw new IllegalStateException("DTO constructor throws on nulls - will fail during select new", e.getCause());
} Try / catch
try {
List<SalesDto> rows = em.createQuery(
"select new com.acme.SalesDto(o.id, sum(l.amount)) from Order o join o.lines l group by o.id",
SalesDto.class).getResultList();
} catch (org.hibernate.query.sqm.sql.internal.InstantiationException e) {
Throwable cause = e.getCause(); // the exception your constructor threw
// fix the constructor (null-handling), then retry
} Prevention
- Keep select-new constructors assignment-only; move logic to factories or post-query mapping.
- Use wrapper types for all constructor parameters so null aggregates bind instead of NPE on unboxing.
- Test each projection query against an empty table and null-valued columns.
When it happens
Trigger: A `select new ...` constructor expression whose constructor throws for particular row values: NPE from unboxing a null argument, parsing/formatting inside the constructor (LocalDate.parse, valueOf), validation or Objects.requireNonNull on arguments, arithmetic on null or unexpected values.
Common situations: DTO constructors doing more than assignment (defensive null checks, normalization) that break on null aggregate results or empty strings; schema changes making columns nullable; constructors shared with other callers that assume non-null; unboxing null SUM()/MAX() results from empty groups.
Related errors
- Error performing the dynamic instantiation
- Cannot set field '{}' to instantiate '{}'
- Error performing the dynamic instantiation
- dynamic instantiation in a sub-query is unsupported
- Error instantiating class '{}' using default constructor: {}
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/d7df49c5a972ff3c.
Report an issue: GitHub.