hibernate/hibernate-orm · error · InstantiationException

Could not instantiate entity

Error message

Could not instantiate entity

What it means

Hibernate throws this org.hibernate.InstantiationException while materializing an embeddable mapped as a Java record, when the record's canonical constructor invocation fails. This instantiator (EmbeddableInstantiatorRecordIndirecting) re-orders the values read from the database into record-component order using its index array and then calls constructor.newInstance(values); any exception thrown by that call (NPE from validation, failed unboxing, IllegalAccessException in modular setups) is wrapped in this InstantiationException with the original as its cause.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/metamodel/internal/EmbeddableInstantiatorRecordIndirecting.java:47

				: new EmbeddableInstantiatorRecordIndirecting( javaType, index );
	}

	@Override
	public Object instantiate(ValueAccess valuesAccess) {
		if ( constructor == null ) {
			throw new InstantiationException( "Unable to locate constructor for embeddable", getMappedPojoClass() );
		}

		try {
			final var originalValues = valuesAccess.getValues();
			final var values = new Object[originalValues.length];
			for ( int i = 0; i < values.length; i++ ) {
				values[i] = originalValues[index[i]];
			}
			return constructor.newInstance( values );
		}
		catch ( Exception e ) {
			throw new InstantiationException( "Could not instantiate entity", getMappedPojoClass(), e );
		}
	}

	// Handles gaps, by leaving the value null for that index
	private static class EmbeddableInstantiatorRecordIndirectingWithGap
			extends EmbeddableInstantiatorRecordIndirecting {

		public EmbeddableInstantiatorRecordIndirectingWithGap(Class<?> javaType, int[] index) {
			super( javaType, index );
		}

		@Override
		public Object instantiate(ValueAccess valuesAccess) {
			if ( constructor == null ) {
				throw new InstantiationException( "Unable to locate constructor for embeddable", getMappedPojoClass() );
			}

			try {

View on GitHub (pinned to fad1729dce)

Solutions

  1. Inspect the cause chain of the InstantiationException (getCause()) - it names the real constructor failure
  2. If columns can be null, use wrapper types in the record and remove null-rejecting checks (Objects.requireNonNull) from the compact constructor
  3. Declare columns NOT NULL in the schema if the record genuinely must reject nulls
  4. Register a custom instantiator with @org.hibernate.annotations.EmbeddableInstantiator (or @IdMappedInstantiator for id embeddables) that converts raw values defensively before calling the constructor
  5. If running under JPMS, add 'opens <entity.package> to hibernate.core' (or hibernate.orm.core) in module-info.java

Example fix

// before - compact constructor rejects nulls from nullable columns
public record Address(String street, String zip) {
    public Address {
        Objects.requireNonNull(street);
    }
}

// after - tolerate nulls, or provide a custom instantiator
public record Address(String street, String zip) {
}

// or, map a default with a custom instantiator
public class AddressInstantiator implements EmbeddableInstantiator {
    @Override
    public Object instantiate(ValueAccess valuesAccess) {
        Object[] v = valuesAccess.getValues();
        return new Address( v[0] == null ? "" : (String) v[0], (String) v[1] );
    }
}

@Embeddable
@EmbeddableInstantiator(AddressInstantiator.class)
public record Address(String street, String zip) {}
Defensive patterns

Strategy: try-catch

Validate before calling

// Before loading, verify nullable columns match null-tolerant record components
boolean safe = true;
for (RecordComponent rc : Address.class.getRecordComponents()) {
    if ( rc.getType().isPrimitive() && columnNullable( rc.getName() ) ) safe = false;
}
if ( !safe ) throw new IllegalStateException("Primitive record component mapped to nullable column");

Try / catch

try {
    return session.find(User.class, id);
}
catch ( org.hibernate.InstantiationException e ) {
    // e.getCause() holds the real constructor failure (NPE, IllegalArgument, ...)
    log.warn("Row {} has embeddable data the record rejects: {}", id, e.getCause());
    return null;
}

Prevention

When it happens

Trigger: Loading or querying a row into an @Embedded/@EmbeddedId record whose compact constructor throws (e.g. Objects.requireNonNull) because a mapped column is null; a record component declared as a primitive (int, boolean) receiving a null column value causing NullPointerException during unboxing; the record living in a Java module (module-info) that does not open its package to hibernate.core, making the canonical constructor inaccessible via reflection.

Common situations: Teams adopting Java records for embeddables with null-validation in compact constructors while the schema still allows NULLs; migrating embeddable fields from wrapper types to primitives; JPQL/Criteria loads of entities containing such embeddables; strong encapsulation under JPMS after moving entities into named modules.

Related errors


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