{"record":{"id":"c86d0bdbc6116afd","repo":"hibernate/hibernate-orm","slug":"attribute-s-of-entity-s-is-mapped-by-associa","errorCode":null,"errorMessage":"Attribute '%s' of entity '%s' is mapped by association '%s' but is not annotated '@EmbeddedId'","messagePattern":"Attribute '(.+?)' of entity '(.+?)' is mapped by association '(.+?)' but is not annotated '@EmbeddedId'","errorType":"exception","errorClass":"AnnotationException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/boot/model/internal/PropertyBinder.java","lineNumber":1513,"sourceCode":"\t\t\t\treturn mapsIdProperty;\n\t\t\t}\n\t\t}\n\t\telse {\n\t\t\treturn collector.getPropertyAnnotatedWithMapsId( classDetails, isId ? \"\" : propertyName );\n\t\t}\n\t}\n\n\tprivate static void checkMappedId(\n\t\t\tPropertyHolder propertyHolder,\n\t\t\tMemberDetails property,\n\t\t\tString propertyName, PropertyData mapsIdProperty,\n\t\t\tInFlightMetadataCollector collector) {\n\t\tfinal var referencedEntityName = mapsIdProperty.getClassOrElementName();\n\t\tfinal var referencedEntityBinding = collector.getEntityBinding( referencedEntityName );\n\t\tif ( referencedEntityBinding != null ) {\n\t\t\tif ( referencedEntityBinding.getIdentifier() instanceof Component compositeId ) {\n\t\t\t\tif ( !isEmbeddedId( property ) ) {\n\t\t\t\t\tthrow new AnnotationException(\n\t\t\t\t\t\t\t\"Attribute '%s' of entity '%s' is mapped by association '%s' but is not annotated '@EmbeddedId'\"\n\t\t\t\t\t\t\t\t\t.formatted(\n\t\t\t\t\t\t\t\t\t\t\tpropertyName,\n\t\t\t\t\t\t\t\t\t\t\tpropertyHolder.getPersistentClass().getEntityName(),\n\t\t\t\t\t\t\t\t\t\t\tmapsIdProperty.getPropertyName()\n\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tfinal String expectedTypeName = compositeId.getComponentClassName();\n\t\t\t\tfinal String actualTypeName = property.getType().getName();\n\t\t\t\tif ( !hasCompatibleType( actualTypeName, expectedTypeName ) ) {\n\t\t\t\t\tthrow new AnnotationException(\n\t\t\t\t\t\t\t\"Identifier attribute '%s' of entity '%s' has type '%s' but is mapped by association '%s' to entity '%s' with composite identifier type '%s'\"\n\t\t\t\t\t\t\t\t\t.formatted(\n\t\t\t\t\t\t\t\t\t\t\tpropertyName,\n\t\t\t\t\t\t\t\t\t\t\tpropertyHolder.getPersistentClass().getEntityName(),\n\t\t\t\t\t\t\t\t\t\t\tactualTypeName,\n\t\t\t\t\t\t\t\t\t\t\tmapsIdProperty.getPropertyName(),","sourceCodeStart":1495,"sourceCodeEnd":1531,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/boot/model/internal/PropertyBinder.java#L1495-L1531","documentation":"Thrown by PropertyBinder.checkMappedId when a @ManyToOne/@OneToOne association uses @MapsId but the referenced entity's identifier is a composite @EmbeddedId while the dependent attribute is not itself annotated @EmbeddedId. JPA derived-identity rules require that when the parent key is an EmbeddedId, the dependent's id must be an EmbeddedId embeddable containing the mapped attribute. Bootstrap fails immediately after Hibernate resolves the referenced entity binding.","triggerScenarios":"Parent entity has @EmbeddedId ParentId id; child declares @MapsId(\"parentId\") on the association but uses a simple @Id Long parentId, or no id at all. Fires when the referenced entity binding is already registered and getIdentifier() returns a Component (composite).","commonSituations":"Converting a simple-key parent to a composite key and forgetting the child's id shape; copying a MapsId pattern from a simple-id example; parent/child tables sharing a composite natural key; teams deriving FK primary keys per JPA 2.4.1 without matching the embeddable shape.","solutions":["Change the child's identifier to an embeddable containing the parent key field and annotate it @EmbeddedId, keeping @MapsId on the association pointing at that field.","If the composite parent key is unwanted, simplify the parent back to a simple @Id so MapsId pairs @Id to @Id.","If you do not need a derived identity, drop @MapsId and map a plain FK column with @JoinColumn."],"exampleFix":"// before (parent has @EmbeddedId ParentId)\n@Id\n@Column(name = \"parent_id\")\nprivate Long parentId; // wrong shape: parent key is composite\n@ManyToOne(fetch = FetchType.LAZY)\n@MapsId(\"parentId\")\nprivate Parent parent;\n\n// after\n@Embeddable\npublic class ChildId implements Serializable {\n    private ParentId parentId; // same embeddable type as parent's id\n}\n\n@EmbeddedId\nprivate ChildId id;\n\n@ManyToOne(fetch = FetchType.LAZY)\n@MapsId(\"parentId\")\nprivate Parent parent;","handlingStrategy":"validation","validationCode":"// before adding classes, assert MapsId children of EmbeddedId parents use EmbeddedId\nfor (Class<?> parent : parentsWithEmbeddedId()) {\n    for (Class<?> child : entitiesMappingIdOf(parent)) {\n        Field f = idAttribute(child);\n        if (!f.isAnnotationPresent(EmbeddedId.class)) {\n            throw new IllegalStateException(child.getSimpleName()\n                + \" maps id of \" + parent.getSimpleName() + \" but lacks @EmbeddedId\");\n        }\n    }\n}","typeGuard":null,"tryCatchPattern":"try {\n    metadata = sources.buildMetadata();\n} catch (AnnotationException e) {\n    // message names the attribute, entity and association - surface it to the mapper\n    failBuild(\"Derived identity misconfigured: \" + e.getMessage());\n}","preventionTips":["Match id shapes across @MapsId pairs: EmbeddedId parent <=> EmbeddedId child; simple parent <=> simple child.","Write one derived-identity IT per parent/child pair in the mapping test suite.","Prefer reusing the parent's embeddable for the child id."],"tags":["hibernate","orm","mapsid","embedded-id","composite-key","mapping"],"backgroundTag":"jpa-mapsid-misuse","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}