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

  1. Read the cause exception and its stack trace - it identifies the failing line inside your constructor.
  2. Make the constructor null-safe: accept object/wrapper types and handle null before unboxing or parsing.
  3. Keep DTO constructors trivial (pure assignment); do normalization/derivation in factory methods or after the query returns.
  4. 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

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


AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22). Data as JSON: /api/errors/d7df49c5a972ff3c. Report an issue: GitHub.