{"record":{"id":"cf1e4106fe7e5727","repo":"hibernate/hibernate-orm","slug":"cannot-instantiate-abstract-class-or-interface","errorCode":null,"errorMessage":"Cannot instantiate abstract class or interface","messagePattern":"Cannot instantiate abstract class or interface","errorType":"exception","errorClass":"InstantiationException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/metamodel/internal/EmbeddableInstantiatorPojoStandard.java","lineNumber":49,"sourceCode":"\t\tsuper( embeddableClass );\n\t\tthis.embeddableMappingAccess = embeddableMappingAccess;\n\t\tthis.constructor = resolveConstructor( embeddableClass );\n\t}\n\n\tprotected static Constructor<?> resolveConstructor(Class<?> mappedPojoClass) {\n\t\ttry {\n\t\t\treturn getDefaultConstructor( mappedPojoClass );\n\t\t}\n\t\tcatch ( PropertyNotFoundException e ) {\n\t\t\tCORE_LOGGER.noDefaultConstructor( mappedPojoClass.getName() );\n\t\t\treturn null;\n\t\t}\n\t}\n\n\t@Override\n\tpublic Object instantiate(ValueAccess valuesAccess) {\n\t\tif ( isAbstract() ) {\n\t\t\tthrow new InstantiationException(\n\t\t\t\t\t\"Cannot instantiate abstract class or interface\", getMappedPojoClass()\n\t\t\t);\n\t\t}\n\n\t\tif ( constructor == null ) {\n\t\t\tthrow new InstantiationException( \"Unable to locate constructor for embeddable\", getMappedPojoClass() );\n\t\t}\n\n\t\ttry {\n\t\t\tfinal var values = valuesAccess == null ? null : valuesAccess.getValues();\n\t\t\tfinal Object instance = constructor.newInstance();\n\t\t\tif ( values != null ) {\n\t\t\t\t// At this point, createEmptyCompositesEnabled is always true.\n\t\t\t\t// We can only set the property values on the compositeInstance though if there is at least one non null value.\n\t\t\t\t// If the values are all null, we would normally not create a composite instance at all because no values exist.\n\t\t\t\t// Setting all properties to null could cause IllegalArgumentExceptions though when the component has primitive properties.\n\t\t\t\t// To avoid this exception and align with what Hibernate 5 did, we skip setting properties if all values are null.\n\t\t\t\t// A possible alternative could be to initialize the resolved values for primitive fields to their default value,","sourceCodeStart":31,"sourceCodeEnd":67,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/metamodel/internal/EmbeddableInstantiatorPojoStandard.java#L31-L67","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\n@Embeddable\npublic abstract class AuditInfo { // abstract -> cannot instantiate\n    private Instant createdAt;\n}\n\n// after\n@Embeddable\npublic class AuditInfo {\n    private Instant createdAt;\n}\n// (or move shared fields to an @MappedSuperclass and keep leaf embeddables concrete)","handlingStrategy":"type-guard","validationCode":"// startup check: no directly-mapped embeddable may be abstract or an interface\nstatic void checkConcrete(Class<?> embeddable) {\n    int mods = embeddable.getModifiers();\n    if (Modifier.isAbstract(mods) || embeddable.isInterface())\n        throw new IllegalStateException(\"@Embeddable must be concrete: \" + embeddable.getName());\n}","typeGuard":"static boolean instantiableEmbeddable(Class<?> clazz) {\n    int mods = clazz.getModifiers();\n    return !Modifier.isAbstract(mods) && !clazz.isInterface()\n            && clazz.getDeclaredConstructors().length > 0;\n}","tryCatchPattern":null,"preventionTips":["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."],"tags":["hibernate","embeddable","abstract-class","instantiation","orm-mapping"],"backgroundTag":"abstract-class-instantiation","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}