hibernate/hibernate-orm · error · InstantiationException

Error performing the dynamic instantiation

Error message

Error performing the dynamic instantiation

What it means

During bean-injection style dynamic instantiation ('select new com.acme.Foo(...) ...' where Hibernate injects values by setter/field because no matching constructor exists), BeanInjectorField.inject() calls Field.set(target, value) under reflection. Any failure - most often the selected value's type not fitting the field's type, or the field being inaccessible/final - is wrapped in InstantiationException('Error performing the dynamic instantiation') with the original exception as cause.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/sql/results/graph/instantiation/internal/BeanInjectorField.java:27

import org.hibernate.query.sqm.sql.internal.InstantiationException;

/**
 * @author Steve Ebersole
 */
class BeanInjectorField<T> implements BeanInjector<T> {
	private final Field field;

	public BeanInjectorField(Field field) {
		this.field = field;
	}

	@Override
	public void inject(T target, Object value) {
		try {
			field.set( target, value );
		}
		catch (Exception e) {
			throw new InstantiationException( "Error performing the dynamic instantiation", e );
		}
	}
}

View on GitHub (pinned to fad1729dce)

Solutions

  1. Read the cause chain - it names the exact reflection failure (IllegalArgumentException 'field type mismatch' is the classic one).
  2. Align the DTO field type with the assembled type (use wrapper/object types: Long, String, BigDecimal; avoid primitives).
  3. Prefer a constructor expression with an explicit matching constructor over field injection - it gives clearer errors and compile-time-ish safety.
  4. Ensure the class is public with non-final fields (or setters), and that reflection into its package is permitted.

Example fix

// before
public class SalesDto { private int total; } // column SUM(...) assembles as Long/BigDecimal
em.createQuery("select new com.acme.SalesDto(sum(l.amount) as total) from Line l", SalesDto.class);
// -> InstantiationException: Can not set int field to Long

// after
public class SalesDto { private Long total; public Long getTotal() { return total; } }
Defensive patterns

Strategy: try-catch

Validate before calling

// At startup, verify each DTO field type accepts the assembled type
for (Field f : SalesDto.class.getDeclaredFields()) {
    if (f.getType() == int.class || f.getType() == long.class || f.getType() == double.class) {
        throw new IllegalStateException("primitive field " + f.getName()
            + " will not accept null aggregate results - use wrapper type");
    }
}

Type guard

// Reflective guard: every aliased select item must be assignable to its target field
static boolean fieldAccepts(Class<?> dto, String alias, Class<?> assembled) {
    try {
        return dto.getDeclaredField(alias).getType().isAssignableFrom(assembled);
    } catch (NoSuchFieldException e) { return false; }
}

Try / catch

try {
    List<SalesDto> rows = q.getResultList();
} catch (org.hibernate.query.sqm.sql.internal.InstantiationException e) {
    Throwable cause = e.getCause();
    // cause is the reflection failure; align DTO field types with the assembled types
}

Prevention

When it happens

Trigger: A dynamic-instantiation query whose aliased argument type differs from the target field's type (e.g. field is int but the column assembles as Long/BigDecimal, or field is an enum but value is String); the target field is final; field access blocked by Java module rules (setAccessible fails).

Common situations: DTO field types not matching JDBC/Hibernate return types (primitives vs wrappers, BigDecimal vs long); refactorings that change DTO field types while the query stays the same; classes in closed modules or non-open JPMS packages; records or immutable classes whose fields cannot be set reflectively.

Related errors


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