{"record":{"id":"2db5968f002ebda1","repo":"hibernate/hibernate-orm","slug":"attribute-attribute-is-declared-as-an-id-o","errorCode":null,"errorMessage":"Attribute '${attribute}' is declared as an '@Id' or '@EmbeddedId' property by '${declaringType}' and so '${respecifyingType}' may not respecify the generation strategy","messagePattern":"Attribute '(.+?)' is declared as an '@Id' or '@EmbeddedId' property by '(.+?)' and so '(.+?)' may not respecify the generation strategy","errorType":"exception","errorClass":"AnnotationException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/boot/model/internal/PropertyBinder.java","lineNumber":773,"sourceCode":"\t\t\tcollector.addPropertyAnnotatedWithMapsId( ownerType.determineRawClass(), propertyAnnotatedElement );\n\t\t}\n\n\t\treturn idPropertyCounter;\n\t}\n\n\tprivate static void checkIdProperty(MemberDetails property, PropertyData propertyData, ModelsContext context) {\n\t\tfinal boolean incomingIdProperty = hasIdAnnotation( property );\n\t\tif ( incomingIdProperty ) {\n\t\t\tfinal var memberDetails = propertyData.getAttributeMember();\n\t\t\tfinal boolean existingIdProperty = hasIdAnnotation( memberDetails );\n\t\t\tif ( existingIdProperty ) {\n\t\t\t\tif ( property.hasDirectAnnotationUsage( GeneratedValue.class )\n\t\t\t\t\t\t|| !property.getMetaAnnotated( IdGeneratorType.class, context ).isEmpty() ) {\n\t\t\t\t\t//TODO: it would be nice to allow a root @Entity to override an\n\t\t\t\t\t//      @Id field declared by a @MappedSuperclass and change the\n\t\t\t\t\t//      generator, but for now we don't seem to be able to detect\n\t\t\t\t\t//      that case here\n\t\t\t\t\tthrow new AnnotationException(\n\t\t\t\t\t\t\t\"Attribute '\" + memberDetails.getName()\n\t\t\t\t\t\t\t+ \"' is declared as an '@Id' or '@EmbeddedId' property by '\"\n\t\t\t\t\t\t\t+ memberDetails.getDeclaringType().getName()\n\t\t\t\t\t\t\t+ \"' and so '\" + property.getDeclaringType().getName()\n\t\t\t\t\t\t\t+ \"' may not respecify the generation strategy\" );\n\t\t\t\t}\n\t\t\t}\n\t\t\telse {\n\t\t\t\t//TODO: it would be nice to allow a root @Entity to override a\n\t\t\t\t//      field declared by a @MappedSuperclass, redeclaring it\n\t\t\t\t//      as an @Id field, but for now we don't seem to be able\n\t\t\t\t//      to detect that case here\n\t\t\t\tthrow new AnnotationException(\n\t\t\t\t\t\t\"Attribute '\" + memberDetails.getName()\n\t\t\t\t\t\t+ \"' is declared by '\" + memberDetails.getDeclaringType().getName()\n\t\t\t\t\t\t+ \"' and may not be redeclared as an '@Id' or '@EmbeddedId' by '\"\n\t\t\t\t\t\t+ property.getDeclaringType().getName() + \"'\" );\n\t\t\t}","sourceCodeStart":755,"sourceCodeEnd":791,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/boot/model/internal/PropertyBinder.java#L755-L791","documentation":"When an @Id is already declared by a superclass (typically a @MappedSuperclass) and a subclass re-specifies the generation strategy — via @GeneratedValue or an @IdGeneratorType-meta-annotated generator — Hibernate rejects the override: generation settings may only be declared where the identifier is declared. This is a deliberate limitation (see the TODO in the source) because reliably detecting a legitimate root-entity override is not currently possible.","triggerScenarios":"A @MappedSuperclass Base declares @Id Long id; the concrete entity redeclares the field with @Id @GeneratedValue(strategy = ...), or adds @GeneratedValue / a custom @IdGeneratorType annotation on the overriding attribute; @AttributeOverride-style field overrides that carry a generator.","commonSituations":"Abstract base entities with a shared @Id where some subclasses want IDENTITY and others SEQUENCE; introducing a generator on a subclass after inheriting the plain id; framework patterns (Spring Data reference templates) that re-annotate inherited id fields.","solutions":["Remove @GeneratedValue (and any @IdGeneratorType annotation) from the subclass override — keep the generator only on the superclass declaration.","If subclasses need different strategies, declare the @Id (with its generator) separately in each concrete root entity instead of inheriting one declaration.","Use a shared @MappedSuperclass WITHOUT @GeneratedValue and put @GeneratedValue on each entity's own @Id if it must redeclare; ensure only one level declares the generator."],"exampleFix":"// before\n@MappedSuperclass\npublic abstract class BaseEntity {\n    @Id\n    protected Long id;\n}\n@Entity\npublic class Order extends BaseEntity {\n    @Override\n    @Id\n    @GeneratedValue(strategy = GenerationType.SEQUENCE)  // rejected\n    public Long getId() { return id; }\n}\n\n// after: generator lives with the declaration\n@MappedSuperclass\npublic abstract class BaseEntity {\n    @Id\n    @GeneratedValue(strategy = GenerationType.SEQUENCE)\n    protected Long id;\n}","handlingStrategy":"validation","validationCode":"// A subclass override of an inherited @Id must not add a generator\nfor (Class<?> entity : annotatedClasses) {\n    Class<?> sup = entity.getSuperclass();\n    while (sup != null && sup.isAnnotationPresent(MappedSuperclass.class)) {\n        for (Field supF : sup.getDeclaredFields()) {\n            if (!supF.isAnnotationPresent(Id.class)) continue;\n            try {\n                Field own = entity.getDeclaredField(supF.getName());\n                if (own.isAnnotationPresent(GeneratedValue.class)) {\n                    throw new IllegalStateException(entity.getName() + \" may not respecify generator for inherited id \" + own.getName());\n                }\n            } catch (NoSuchFieldException ignored) { }\n        }\n        sup = sup.getSuperclass();\n    }\n}","typeGuard":null,"tryCatchPattern":"try {\n    SessionFactory sf = cfg.buildSessionFactory();\n} catch (AnnotationException e) {\n    throw new IllegalStateException(\"Id generation redefinition: \" + e.getMessage(), e);\n}","preventionTips":["Declare @GeneratedValue exactly once, where the @Id is declared","If per-entity strategies are needed, don't inherit the id from a mapped superclass"],"tags":["hibernate","jpa","id","generatedvalue","mapped-superclass","inheritance","bootstrap"],"backgroundTag":"inherited-id-override-conflict","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}