{"record":{"id":"fce92111bc247168","repo":"hibernate/hibernate-orm","slug":"entity-propertyholder-getentityname-is","errorCode":null,"errorMessage":"Entity '\" + propertyHolder.getEntityName() + \"' is a subclass in an entity class hierarchy and may not have a property annotated '@Version'","messagePattern":"Entity '\" \\+ propertyHolder\\.getEntityName\\(\\) \\+ \"' is a subclass in an entity class hierarchy and 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":1099,"sourceCode":"\t\t\t\tmappedSuperclass.setDeclaredVersion( property );\n\t\t\t}\n\t\t}\n\t\telse {\n\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) {","sourceCodeStart":1081,"sourceCodeEnd":1117,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/boot/model/internal/PropertyBinder.java#L1081-L1117","documentation":"In an inherited entity hierarchy the @Version property may only be declared on the root entity, because there is exactly one version column per hierarchy and it is owned by the root table. Declaring @Version on a subclass fails the RootClass check in checkVersionProperty and throws AnnotationException.","triggerScenarios":"@Entity subclass (SINGLE_TABLE, JOINED, or TABLE_PER_CLASS) with its own @Version field; refactoring that moves the version property from the root into a subtype; adding @Version to one subclass because only that subtype needed locking.","commonSituations":"Introducing optimistic locking piecemeal into an existing hierarchy; merging independently-developed entities under a common base where a subtype already had a version column; generated per-subclass templates that include version fields.","solutions":["Move the @Version property to the root @Entity of the hierarchy (all subtypes share it).","Remove the duplicate @Version from the subclass if the root already declares one.","If per-subtype versioning is genuinely required, the types cannot share one inheritance hierarchy — split them into separate root entities."],"exampleFix":"// before\n@Entity\n@Inheritance(strategy = InheritanceType.JOINED)\npublic abstract class Item { ... }\n@Entity\npublic class Book extends Item {\n    @Version            // rejected: not the root\n    private int version;\n}\n\n// after\npublic abstract class Item {\n    @Version\n    private int version;\n}\n// subclass: no @Version","handlingStrategy":"validation","validationCode":"// Only the hierarchy root may carry @Version\nfor (Class<?> entity : annotatedClasses) {\n    Class<?> sup = entity.getSuperclass();\n    if (sup != null && sup.isAnnotationPresent(Entity.class)) {\n        for (Field f : entity.getDeclaredFields()) {\n            if (f.isAnnotationPresent(Version.class)) {\n                throw new IllegalStateException(\"Subclass \" + entity.getName() + \" declares @Version; move it to the root\");\n            }\n        }\n    }\n}","typeGuard":"static boolean isRootOfEntityHierarchy(Class<?> c) {\n    return c.getSuperclass() == null || !c.getSuperclass().isAnnotationPresent(Entity.class);\n}","tryCatchPattern":"try {\n    SessionFactory sf = cfg.buildSessionFactory();\n} catch (AnnotationException e) {\n    throw new IllegalStateException(\"@Version placement invalid: \" + e.getMessage(), e);\n}","preventionTips":["Declare @Version once on the hierarchy root before adding subclasses","When merging entities under a base class, remove duplicate version fields from subtypes"],"tags":["hibernate","jpa","version","inheritance","subclass","bootstrap"],"backgroundTag":"version-property-misplaced","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}