{"record":{"id":"8049a6e2d15debdb","repo":"hibernate/hibernate-orm","slug":"property-property-uses-to-many-mapping-with","errorCode":null,"errorMessage":"Property '${property}' uses *-to-many mapping with mappedBy '${mappedByProperty}' in the aggregate component class '${componentClassName}' within an array property, which is not allowed.","messagePattern":"Property '(.+?)' uses \\*-to-many mapping with mappedBy '(.+?)' in the aggregate component class '(.+?)' within an array property, which is not allowed\\.","errorType":"exception","errorClass":"AnnotationException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/boot/model/internal/AggregateComponentSecondPass.java","lineNumber":203,"sourceCode":"\t\t\tfinal Value value = property.getValue();\n\t\t\tif ( value instanceof Component comp ) {\n\t\t\t\tvalidateComponent( comp, qualify( basePath, property.getName() ), inArray );\n\t\t\t}\n\t\t\telse if ( value instanceof ToOne toOne ) {\n\t\t\t\tif ( inArray && toOne.getReferencedPropertyName() != null ) {\n\t\t\t\t\tthrow new AnnotationException(\n\t\t\t\t\t\t\t\"Property '\" + qualify( basePath, property.getName() )\n\t\t\t\t\t\t\t\t\t+ \"' uses one-to-one mapping with mappedBy '\"\n\t\t\t\t\t\t\t\t\t+ toOne.getReferencedPropertyName()\n\t\t\t\t\t\t\t\t\t+ \"' in the aggregate component class '\"\n\t\t\t\t\t\t\t\t\t+ component.getComponentClassName()\n\t\t\t\t\t\t\t\t\t+ \"' within an array property, which is not allowed.\"\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if ( value instanceof Collection collection ) {\n\t\t\t\tif ( inArray && collection.getMappedByProperty() != null ) {\n\t\t\t\t\tthrow new AnnotationException(\n\t\t\t\t\t\t\t\"Property '\" + qualify( basePath, property.getName() )\n\t\t\t\t\t\t\t\t\t+ \"' uses *-to-many mapping with mappedBy '\"\n\t\t\t\t\t\t\t\t\t+ collection.getMappedByProperty()\n\t\t\t\t\t\t\t\t\t+ \"' in the aggregate component class '\"\n\t\t\t\t\t\t\t\t\t+ component.getComponentClassName()\n\t\t\t\t\t\t\t\t\t+ \"' within an array property, which is not allowed.\"\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tif ( inArray && collection.getCollectionTable() != null ) {\n\t\t\t\t\tthrow new AnnotationException(\n\t\t\t\t\t\t\t\"Property '\" + qualify( basePath, property.getName() )\n\t\t\t\t\t\t\t\t\t+ \"' defines a collection table '\"\n\t\t\t\t\t\t\t\t\t+ collection.getCollectionTable()\n\t\t\t\t\t\t\t\t\t+ \"' in the aggregate component class '\"\n\t\t\t\t\t\t\t\t\t+ component.getComponentClassName()\n\t\t\t\t\t\t\t\t\t+ \"' within an array property, which is not allowed.\"\n\t\t\t\t\t);\n\t\t\t\t}","sourceCodeStart":185,"sourceCodeEnd":221,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/boot/model/internal/AggregateComponentSecondPass.java#L185-L221","documentation":"Same validation pass as the one-to-one case: AggregateComponentSecondPass.validateComponent rejects any Collection-typed property inside an array-bound aggregate that declares mappedBy (getMappedByProperty() != null), i.e. a bidirectional @OneToMany/@ManyToMany. Struct elements stored in arrays cannot be inverse sides of a relationship.","triggerScenarios":"An embeddable used inside an @Array or aggregate element-collection contains @OneToMany(mappedBy = ...) or @ManyToMany(mappedBy = ...), triggering the inArray validation during the second pass.","commonSituations":"Copying working entity patterns (bidirectional collections) into a new struct aggregate; embedding an existing @Embeddable with collection associations into an array column; schema-first designs where the struct was modeled like a mini-entity.","solutions":["Move the @OneToMany/@ManyToMany out of the embeddable onto the owning entity","If the collection is really part of the struct value, model it as a nested aggregate array instead of an association","Remove mappedBy if the collection must stay (unidirectional join from the struct side is usually still wrong - prefer moving it out)","Stop using the embeddable inside arrays and map it as a first-level component"],"exampleFix":"// before: bidirectional many-side inside an array aggregate\n@Embeddable\npublic class OrderLine {\n    @OneToMany(mappedBy = \"orderLine\")      // rejected: mappedBy within array aggregate\n    private List<Attachment> attachments;\n}\n\n@Entity\npublic class Order {\n    @Array\n    private List<OrderLine> lines;\n}\n\n// after: ownership lives on the entity; the aggregate keeps only value data\n@Embeddable\npublic class OrderLine { /* value fields only */ }\n\n@Entity\npublic class Attachment {\n    @ManyToOne @JoinColumn(name = \"order_id\")\n    private Order order;\n}","handlingStrategy":"validation","validationCode":"// Before boot: aggregates used in arrays must not contain mappedBy collections\nstatic boolean aggregateHasNoMappedByCollections(Class<?> embeddable) {\n    for (Field f : embeddable.getDeclaredFields()) {\n        OneToMany otm = f.getAnnotation(OneToMany.class);\n        ManyToMany mtm = f.getAnnotation(ManyToMany.class);\n        if ((otm != null && !otm.mappedBy().isEmpty())\n                || (mtm != null && !mtm.mappedBy().isEmpty())) {\n            return false;\n        }\n    }\n    return true;\n}","typeGuard":null,"tryCatchPattern":"try {\n    final SessionFactory sf = new MetadataSources(standardServiceRegistry)\n            .addAnnotatedClass(MyEntity.class)\n            .buildMetadata()\n            .buildSessionFactory();\n} catch (AnnotationException | MappingException e) {\n    throw new IllegalStateException(\"Invalid ORM mapping, aborting startup: \" + e.getMessage(), e);\n}","preventionTips":["Never declare associations inside value-type embeddables; keep them on entities","Review every embeddable before reusing it inside an @Array aggregate","Validate the full mapping in CI with a SessionFactory build"],"tags":["hibernate","struct","aggregate","one-to-many","many-to-many","mapped-by","array","mapping"],"backgroundTag":"aggregate-struct-association-restriction","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}