{"record":{"id":"e6bb821d20a53d48","repo":"hibernate/hibernate-orm","slug":"property-property-uses-one-to-one-mapping-wit","errorCode":null,"errorMessage":"Property '${property}' uses one-to-one mapping with mappedBy '${referencedPropertyName}' in the aggregate component class '${componentClassName}' within an array property, which is not allowed.","messagePattern":"Property '(.+?)' uses one-to-one 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":191,"sourceCode":"\t\t\t\t\t\tsubColumn\n\t\t\t\t);\n\t\t\t}\n\t\t\tsubColumn.setAssignmentExpression( assignmentExpression );\n\t\t\tsubColumn.setCustomRead( customReadExpression );\n\t\t}\n\n\t\tpropertyHolder.getTable().getColumns().removeAll( aggregatedColumns );\n\t}\n\n\tprivate static void validateComponent(Component component, String basePath, boolean inArray) {\n\t\tfor ( Property property : component.getProperties() ) {\n\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.\"","sourceCodeStart":173,"sourceCodeEnd":209,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/boot/model/internal/AggregateComponentSecondPass.java#L173-L209","documentation":"AggregateComponentSecondPass.validateComponent walks every property of an embeddable that is mapped inside an array (inArray=true). Structs stored in arrays cannot own inverse sides, so any ToOne association that declares a mappedBy (getReferencedPropertyName() != null) - i.e. a bidirectional @OneToOne/@ManyToOne - is rejected with this AnnotationException.","triggerScenarios":"An embeddable (directly or nested) used inside an @Array/element-collection-of-aggregates contains @OneToOne(mappedBy = ...) (or any to-one with a referenced property), and the whole component is stored within an array property of an entity.","commonSituations":"Reusing an existing embeddable that worked as a plain @Embedded attribute inside a new array aggregate; making a struct bidirectional by adding mappedBy; Hibernate 6->7 migration where aggregate validation became stricter.","solutions":["Remove mappedBy from the association inside the embeddable so it is unidirectional","Better: move the association out of the aggregate embeddable onto the owning entity","Replace the association with a plain FK column stored in the struct if ownership info is needed","Restructure so the embeddable is not used within an array (map as separate table/entity)"],"exampleFix":"// before: bidirectional to-one inside an aggregate that is used in an array\n@Embeddable\npublic class ContactInfo {\n    @OneToOne(mappedBy = \"contactInfo\")     // rejected inside array aggregates\n    private Person person;\n}\n\n@Entity\npublic class Customer {\n    @Array\n    private List<ContactInfo> contacts;\n}\n\n// after: keep the aggregate association-free; own the link from the entity side\n@Embeddable\npublic class ContactInfo { /* value fields only */ }\n\n@Entity\npublic class Person {\n    @ManyToOne\n    @JoinColumn(name = \"customer_id\")\n    private Customer customer;\n}","handlingStrategy":"validation","validationCode":"// Before boot: reject aggregates destined for arrays that contain mappedBy associations\nstatic boolean aggregateIsArraySafe(Class<?> embeddable) {\n    for (Field f : embeddable.getDeclaredFields()) {\n        OneToOne o2o = f.getAnnotation(OneToOne.class);\n        ManyToOne m2o = f.getAnnotation(ManyToOne.class);\n        if ((o2o != null && !o2o.mappedBy().isEmpty())\n                || (m2o != null && !m2o.mappedBy().isEmpty())) {\n            return false;\n        }\n        if (f.getType().isAnnotationPresent(Embeddable.class)\n                && !aggregateIsArraySafe(f.getType())) {\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":["Treat aggregate embeddables as pure value types: no mappedBy, no collection tables","Keep bidirectionality on entity classes, never inside structs","Add a mapping smoke test for every embeddable reused inside arrays"],"tags":["hibernate","struct","aggregate","one-to-one","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"}