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

  1. Make the embeddable class concrete (drop abstract) if it is directly used by @Embedded/@ElementCollection.
  2. For shared field declarations among embeddables, move them to an @MappedSuperclass and keep every leaf @Embeddable concrete.
  3. For polymorphic embeddables, supply @EmbeddableInstantiator on each concrete subclass (or use EmbeddableInstantiatorRegistration) so the abstract base is never instantiated.
  4. 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

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


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