{"record":{"id":"bdbe02b5adeae525","repo":"hibernate/hibernate-orm","slug":"could-not-instantiate-entity-bdbe02","errorCode":null,"errorMessage":"Could not instantiate entity","messagePattern":"Could not instantiate entity","errorType":"exception","errorClass":"InstantiationException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/metamodel/internal/EmbeddableInstantiatorPojoStandard.java","lineNumber":76,"sourceCode":"\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,\n\t\t\t\t// but that might cause unexpected outcomes for Hibernate 5 users that use createEmptyCompositesEnabled when updating.\n\t\t\t\t// You can see the need for this by running EmptyCompositeEquivalentToNullTest\n\t\t\t\tembeddableMappingAccess.get().setValues( instance, values );\n\t\t\t}\n\n\t\t\treturn instance;\n\t\t}\n\t\tcatch ( Exception e ) {\n\t\t\tthrow new InstantiationException( \"Could not instantiate entity\", getMappedPojoClass(), e );\n\t\t}\n\t}\n}\n","sourceCodeStart":58,"sourceCodeEnd":80,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/metamodel/internal/EmbeddableInstantiatorPojoStandard.java#L58-L80","documentation":"This is the catch-all of EmbeddableInstantiatorPojoStandard.instantiate: after the abstract-class and constructor-null guards pass, it calls constructor.newInstance() and then embeddableMappingAccess.get().setValues(instance, values) to push the loaded state onto the fresh instance. Any Exception thrown there — constructor failure, setter/field write problems (wrong type, access denied, setter threw) — is wrapped as InstantiationException(\"Could not instantiate entity\") with the original cause preserved.","triggerScenarios":"Hydrating an @Embedded/@ElementCollection attribute where the no-arg constructor throws, or where writing a property value fails: type mismatch between the mapped property and the loaded value (e.g. after changing a field type without schema migration), setters with validation that rejects loaded values, or JPMS/SecurityManager blocking reflective writes.","commonSituations":"Setter methods that validate and throw on legacy/bad data already in the table; entity type changed (String -> enum) while old rows hold unmappable values; private final fields without accessible setters after refactors; constructors with side effects (logging, service calls) that throw in the persistence context; modules not open to hibernate.core.","solutions":["Unwrap the cause chain — the real failure (NPE in ctor, IllegalArgumentException from a setter, IllegalAccessException) names the exact field/method to fix.","Make property setters/fields writable by Hibernate: avoid throwing validation in setters used for hydration; move validation to @PrePersist/@PreUpdate.","After changing property types, migrate or clean existing data so setValues receives convertible values.","Under JPMS, ensure the embeddable's package is open (opens com.example.model to hibernate.core or all-unnamed) so reflective writes succeed."],"exampleFix":"// before\n@Embeddable\npublic class Email {\n    private String value;\n    public void setValue(String value) {\n        if (!value.contains(\"@\")) throw new IllegalArgumentException(); // breaks hydration of legacy rows\n        this.value = value;\n    }\n}\n\n// after\n@Embeddable\npublic class Email {\n    private String value;\n    public void setValue(String value) {\n    \tthis.value = value; // validate in @PrePersist/@PreUpdate instead\n    }\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n    Entity e = session.find(Entity.class, id);\n} catch (InstantiationException e) {\n    if (\"Could not instantiate entity\".equals(e.getMessage())) {\n        Throwable cause = e.getCause(); // real failure: ctor threw, setter rejected value, access denied\n        log.error(\"Embeddable hydration failed for {}\", e.getClassName(), cause);\n    }\n    throw e;\n}","preventionTips":["Do not throw from setters used during hydration — validate in entity lifecycle callbacks.","After changing embeddable property types, migrate stored data before deploying.","Open the embeddable package under JPMS so reflective field writes succeed."],"tags":["hibernate","embeddable","instantiation","reflection","hydration"],"backgroundTag":"embeddable-instantiation-failed","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}