hibernate/hibernate-orm · error · InstantiationException
Cannot instantiate abstract class or interface
Error message
Cannot instantiate abstract class or interface
What it means
EmbeddableInstantiatorPojoStandard is the default instantiator for @Embeddable classes without a custom instantiator or injected constructor. Its instantiate(ValueAccess) first checks isAbstract() on the mapped POJO class and throws InstantiationException("Cannot instantiate abstract class or interface") because reflection cannot construct an abstract type. Hibernate needs a concrete class to call new on for every embedded instance.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/metamodel/internal/EmbeddableInstantiatorPojoStandard.java:49
super( embeddableClass );
this.embeddableMappingAccess = embeddableMappingAccess;
this.constructor = resolveConstructor( embeddableClass );
}
protected static Constructor<?> resolveConstructor(Class<?> mappedPojoClass) {
try {
return getDefaultConstructor( mappedPojoClass );
}
catch ( PropertyNotFoundException e ) {
CORE_LOGGER.noDefaultConstructor( mappedPojoClass.getName() );
return null;
}
}
@Override
public Object instantiate(ValueAccess valuesAccess) {
if ( isAbstract() ) {
throw new InstantiationException(
"Cannot instantiate abstract class or interface", getMappedPojoClass()
);
}
if ( constructor == null ) {
throw new InstantiationException( "Unable to locate constructor for embeddable", getMappedPojoClass() );
}
try {
final var values = valuesAccess == null ? null : valuesAccess.getValues();
final Object instance = constructor.newInstance();
if ( values != null ) {
// At this point, createEmptyCompositesEnabled is always true.
// We can only set the property values on the compositeInstance though if there is at least one non null value.
// If the values are all null, we would normally not create a composite instance at all because no values exist.
// Setting all properties to null could cause IllegalArgumentExceptions though when the component has primitive properties.
// To avoid this exception and align with what Hibernate 5 did, we skip setting properties if all values are null.
// A possible alternative could be to initialize the resolved values for primitive fields to their default value,View on GitHub (pinned to fad1729dce)
Solutions
- Make the embeddable class concrete (drop abstract) if it is directly used by @Embedded/@ElementCollection.
- For shared field declarations among embeddables, move them to an @MappedSuperclass and keep every leaf @Embeddable concrete.
- For polymorphic embeddables, supply @EmbeddableInstantiator on each concrete subclass (or use EmbeddableInstantiatorRegistration) so the abstract base is never instantiated.
- Check any @Embedded/@EmbeddedId targets resolve to concrete classes with a metamodel smoke test.
Example fix
// before
@Embeddable
public abstract class AuditInfo { // abstract -> cannot instantiate
private Instant createdAt;
}
// after
@Embeddable
public class AuditInfo {
private Instant createdAt;
}
// (or move shared fields to an @MappedSuperclass and keep leaf embeddables concrete) Defensive patterns
Strategy: type-guard
Validate before calling
// startup check: no directly-mapped embeddable may be abstract or an interface
static void checkConcrete(Class<?> embeddable) {
int mods = embeddable.getModifiers();
if (Modifier.isAbstract(mods) || embeddable.isInterface())
throw new IllegalStateException("@Embeddable must be concrete: " + embeddable.getName());
} Type guard
static boolean instantiableEmbeddable(Class<?> clazz) {
int mods = clazz.getModifiers();
return !Modifier.isAbstract(mods) && !clazz.isInterface()
&& clazz.getDeclaredConstructors().length > 0;
} Prevention
- Use @MappedSuperclass, not @Embeddable abstract classes, for shared embeddable fields.
- For polymorphic embeddables, register a concrete @EmbeddableInstantiator per subclass.
- Lint mappings: every @Embedded/@EmbeddedId target must be a concrete class.
When it happens
Trigger: An @Embeddable class declared abstract (common to hold shared fields with @MappedSuperclass semantics by mistake) used via @Embedded in an entity; a mapped interface annotated @Embeddable; element collections of an abstract embeddable type without a custom instantiator; abstract subclass in an embeddable inheritance arrangement.
Common situations: Developers use @Embeddable where @MappedSuperclass was intended, leaving the common class abstract; embeddable type hierarchies (e.g., an abstract Contact base with EmailContact/PhoneContact) without per-subclass instantiators registered; refactoring concrete classes to abstract during cleanup while mappings still reference them as the embeddable target.
Related errors
- Unable to locate constructor for embeddable
- Class '<componentClassName>' is an '@Embeddable' type and ma
- Class '<componentClassName>' is an '@Embeddable' type and ma
- Could not instantiate entity
- Could not instantiate entity
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/cf1e4106fe7e5727.
Report an issue: GitHub.