{"record":{"id":"1cac73a5765df839","repo":"hibernate/hibernate-orm","slug":"embedded-class-propertyholder-getentityname","errorCode":null,"errorMessage":"Embedded class '\" + propertyHolder.getEntityName() + \"' may not have a property annotated '@Version'","messagePattern":"Embedded class '\" \\+ propertyHolder\\.getEntityName\\(\\) \\+ \"' may not have a property annotated '@Version'","errorType":"exception","errorClass":"AnnotationException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/boot/model/internal/PropertyBinder.java","lineNumber":1103,"sourceCode":"\t\t\t//we know the property is on the actual entity\n\t\t\trootClass.setDeclaredVersion( property );\n\t\t}\n\n\t\trootClass.setOptimisticLockStyle( OptimisticLockStyle.VERSION );\n\t}\n\n\tprivate static void checkVersionProperty(PropertyHolder propertyHolder, boolean isIdentifierMapper) {\n\t\tif ( isIdentifierMapper ) {\n\t\t\tthrow new AnnotationException( \"Class '\" + propertyHolder.getEntityName()\n\t\t\t\t\t+ \"' is annotated '@IdClass' and may not have a property annotated '@Version'\"\n\t\t\t);\n\t\t}\n\t\tif ( !( propertyHolder.getPersistentClass() instanceof RootClass ) ) {\n\t\t\tthrow new AnnotationException( \"Entity '\" + propertyHolder.getEntityName()\n\t\t\t\t\t+ \"' is a subclass in an entity class hierarchy and may not have a property annotated '@Version'\" );\n\t\t}\n\t\tif ( !propertyHolder.isEntity() ) {\n\t\t\tthrow new AnnotationException( \"Embedded class '\" + propertyHolder.getEntityName()\n\t\t\t\t\t+ \"' may not have a property annotated '@Version'\" );\n\t\t}\n\t}\n\n\tprivate AnnotatedColumns bindBasicOrComposite(\n\t\t\tPropertyHolder propertyHolder,\n\t\t\tNullability nullability,\n\t\t\tPropertyData inferredData,\n\t\t\tEntityBinder entityBinder,\n\t\t\tboolean isIdentifierMapper,\n\t\t\tboolean isComponentEmbedded,\n\t\t\tColumnsBuilder columnsBuilder,\n\t\t\tAnnotatedColumns columns,\n\t\t\tClassDetails returnedClass) {\n\t\tfinal var memberDetails = inferredData.getAttributeMember();\n\n\t\tif ( propertyHolder.isEntity() && propertyHolder.getPersistentClass().isAbstract() ) {\n\t\t\t// When the type of the member is a type variable, we mark it as generic for abstract classes","sourceCodeStart":1085,"sourceCodeEnd":1121,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/boot/model/internal/PropertyBinder.java#L1085-L1121","documentation":"@Version is only valid on entity classes; an embeddable/component class has no independent optimistic-lock lifecycle of its own, so checkVersionProperty throws AnnotationException when the property holder is not an entity. The version must live on the owning entity.","triggerScenarios":"A field annotated @Version inside an @Embeddable class (e.g. an audit embeddable reused across entities); embeddables assembled from copied entity code that retained the version field.","commonSituations":"Shared 'Auditable' embeddables that bundle createdAt/updatedAt plus a version column; refactoring that moved the version property into a component; scaffolding that treats embeddables like mini-entities.","solutions":["Remove @Version from the embeddable member and declare @Version on the owning entity.","If the embeddable tracks timestamps only, keep createdAt/updatedAt with @CreationTimestamp/@UpdateTimestamp and no @Version.","Alternatively map the component's version column as a plain immutable field managed by the application."],"exampleFix":"// before\n@Embeddable\npublic class Audit {\n    @Version             // rejected: holder is not an entity\n    private int version;\n}\n\n// after\n@Embeddable\npublic class Audit { /* timestamps only */ }\n@Entity\npublic class Document {\n    @Embedded\n    private Audit audit;\n    @Version\n    private int version;\n}","handlingStrategy":"validation","validationCode":"// Embeddables must not declare @Version\nfor (Class<?> cls : annotatedClasses) {\n    if (cls.isAnnotationPresent(Embeddable.class)) {\n        for (Field f : cls.getDeclaredFields()) {\n            if (f.isAnnotationPresent(Version.class)) {\n                throw new IllegalStateException(\"Embeddable \" + cls.getName() + \" declares @Version field \" + f.getName());\n            }\n        }\n    }\n}","typeGuard":null,"tryCatchPattern":"try {\n    SessionFactory sf = cfg.buildSessionFactory();\n} catch (AnnotationException e) {\n    throw new IllegalStateException(\"@Version in embeddable: \" + e.getMessage(), e);\n}","preventionTips":["Keep version state on entities; embeddables carry values, not lifecycle","Use @CreationTimestamp/@UpdateTimestamp inside audit embeddables instead of @Version"],"tags":["hibernate","jpa","version","embeddable","optimistic-lock","bootstrap"],"backgroundTag":"version-property-misplaced","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}