hibernate/hibernate-orm · error · InstantiationException
Unable to locate constructor for embeddable
Error message
Unable to locate constructor for embeddable
What it means
Thrown by EmbeddableInstantiatorRecordStandard.instantiate when the constructor resolved in the class constructor phase is null. The constructor is looked up once via getConstructorOrNull(javaType, getRecordComponentTypes(javaType)); it remains null when the mapped embeddable class does not expose a constructor whose parameter types match the record component types - in practice, when record representation is used for a class that is not a genuine record, or whose canonical constructor cannot be reflectively matched.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/metamodel/internal/EmbeddableInstantiatorRecordStandard.java:31
import static org.hibernate.internal.util.ReflectHelper.getConstructorOrNull;
import static org.hibernate.internal.util.ReflectHelper.getRecordComponentTypes;
/**
* Support for instantiating embeddables as record representation
*/
public class EmbeddableInstantiatorRecordStandard extends AbstractPojoInstantiator implements EmbeddableInstantiator {
protected final Constructor<?> constructor;
public EmbeddableInstantiatorRecordStandard(Class<?> javaType) {
super( javaType );
constructor = getConstructorOrNull( javaType, getRecordComponentTypes( javaType ) );
}
@Override
public Object instantiate(ValueAccess valuesAccess) {
if ( constructor == null ) {
throw new InstantiationException( "Unable to locate constructor for embeddable", getMappedPojoClass() );
}
try {
return constructor.newInstance( valuesAccess.getValues() );
}
catch ( Exception e ) {
throw new InstantiationException( "Could not instantiate entity", getMappedPojoClass(), e );
}
}
}
View on GitHub (pinned to fad1729dce)
Solutions
- Confirm the mapped class is a real record and the mapping uses it directly (not a wrapper class with @Representation(RECORD))
- If the class must stay a POJO, remove the record representation setting and let Hibernate use POJO instantiation
- For CompositeUserType, make returnedClass() return the record class whose canonical constructor matches the mapped property types
- Catch InstantiationException during a warm-up read right after SessionFactory creation so mapping problems surface at startup, not in production queries
Example fix
// before - CompositeUserType returns a non-record holder but mapping declares RECORD
public class MoneyType implements CompositeUserType<MoneyHolder> {
public Class<MoneyHolder> returnedClass() { return MoneyHolder.class; } // plain class
}
// after - return the actual record
type public class MoneyType implements CompositeUserType<Money> {
public Class<Money> returnedClass() { return Money.class; } // record
}
public record Money(BigDecimal amount, Currency currency) {} Defensive patterns
Strategy: validation
Validate before calling
// Fail fast at app start instead of first query
Class<?> embeddable = Money.class;
if ( !embeddable.isRecord() ) {
throw new IllegalStateException("Embeddable " + embeddable.getName() + " must be a record under RECORD representation");
}
Class<?>[] ctorTypes = Arrays.stream(embeddable.getRecordComponents()).map(RecordComponent::getType).toArray(Class[]::new);
embeddable.getDeclaredConstructor(ctorTypes).setAccessible(true); // throws if unresolvable/inaccessible Type guard
static boolean hasCanonicalRecordConstructor(Class<?> c) {
if (!c.isRecord()) return false;
try {
Class<?>[] t = Arrays.stream(c.getRecordComponents()).map(RecordComponent::getType).toArray(Class[]::new);
c.getDeclaredConstructor(t);
return true;
} catch (NoSuchMethodException | SecurityException e) { return false; }
} Try / catch
catch ( org.hibernate.InstantiationException e ) {
if ( "Unable to locate constructor for embeddable".equals(e.getMessage()) ) {
throw new MappingError("Embeddable " + e.getMessage() + " has no canonical record constructor - fix the mapping", e);
}
throw e;
} Prevention
- Keep the embeddable class a plain record and let Hibernate resolve the canonical constructor itself
- Make CompositeUserType.returnedClass() return the actual record class
- Smoke-test EntityManagerFactory creation plus one entity load per embeddable in CI
When it happens
Trigger: Boot succeeds but the first load/query of the embeddable calls instantiate() and hits the null-constructor branch; @Representation(RepresentationMode.RECORD) on a non-record embeddable class; a record type consumed through a custom CompositeUserType whose returnedClass is not the record itself; record loaded through a JavaType descriptor reporting non-matching component types.
Common situations: Hibernate 6 migrations where RepresentationMode.RECORD was introduced to keep old mappings; misconfigured CompositeUserType implementations; annotation processors generating embeddable stubs that are not records.
Related errors
- Could not instantiate entity
- Could not instantiate entity
- Class '<componentClassName>' is an '@Embeddable' type and ma
- Class '<componentClassName>' is an '@Embeddable' type and ma
- Property '${path}' specifies ${columnCount} '@AttributeOverr
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/35f0ca262c63399a.
Report an issue: GitHub.