{"record":{"id":"8bbe546ff74953ca","repo":"hibernate/hibernate-orm","slug":"attribute-s-referenced-columns-from-multiple-ta","errorCode":null,"errorMessage":"Attribute [%s] referenced columns from multiple tables: %s, %s","messagePattern":"Attribute \\[(.+?)\\] referenced columns from multiple tables: (.+?), (.+?)","errorType":"exception","errorClass":"MappingException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/boot/model/source/internal/hbm/ModelBinder.java","lineNumber":1368,"sourceCode":"\n\tprivate Identifier determineTable(\n\t\t\tMappingDocument sourceDocument,\n\t\t\tString attributeName,\n\t\t\tRelationalValueSourceContainer relationalValueSourceContainer) {\n\t\treturn determineTable( sourceDocument, attributeName,\n\t\t\t\trelationalValueSourceContainer.getRelationalValueSources() );\n\t}\n\n\tprivate Identifier determineTable(\n\t\t\tMappingDocument mappingDocument,\n\t\t\tSingularAttributeSourceEmbedded embeddedAttributeSource) {\n\t\tIdentifier tableName = null;\n\t\tfor ( var attributeSource : embeddedAttributeSource.getEmbeddableSource().attributeSources() ) {\n\t\t\tfinal Identifier determinedName =\n\t\t\t\t\tdetermineTableName( mappingDocument, embeddedAttributeSource, attributeSource );\n\t\t\tif ( determinedName != null && !determinedName.equals( tableName ) ) {\n\t\t\t\tif ( tableName != null ) {\n\t\t\t\t\tthrow new MappingException(\n\t\t\t\t\t\t\t\"Attribute [%s] referenced columns from multiple tables: %s, %s\"\n\t\t\t\t\t\t\t\t\t.formatted( embeddedAttributeSource.getAttributeRole().getFullPath(),\n\t\t\t\t\t\t\t\t\t\t\ttableName, determinedName ),\n\t\t\t\t\t\t\tmappingDocument.getOrigin()\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\ttableName = determinedName;\n\t\t\t}\n\t\t}\n\t\treturn tableName;\n\t}\n\n\tprivate Identifier determineTableName(MappingDocument mappingDocument, SingularAttributeSourceEmbedded embeddedAttributeSource, AttributeSource attributeSource) {\n\t\tif ( attributeSource instanceof RelationalValueSourceContainer relationalValueSourceContainer ) {\n\t\t\treturn determineTable(\n\t\t\t\t\tmappingDocument,\n\t\t\t\t\tembeddedAttributeSource.getAttributeRole().getFullPath(),\n\t\t\t\t\trelationalValueSourceContainer","sourceCodeStart":1350,"sourceCodeEnd":1386,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/boot/model/source/internal/hbm/ModelBinder.java#L1350-L1386","documentation":"For an <component> (embedded) attribute, Hibernate walks the embeddable's attribute sources and derives the single containing table for the embedded's columns, because a component's columns must all live in one table. If two sub-attributes resolve to different non-null table names, determineTable throws this MappingException naming the attribute role and both conflicting tables.","triggerScenarios":"A <component name='...' class='...'> whose nested <property>/<many-to-one> elements carry explicit table= attributes pointing at different tables; a component nested in a <join> (secondary table) where some sub-attributes name the primary table and others the join table.","commonSituations":"Copy-pasting column definitions from an entity with secondary tables into a component; stale table references left behind after table renames; moving a component between classes without cleaning per-column table overrides.","solutions":["Remove the explicit table= attributes from the component's sub-attribute columns so they all default to the containing table","If the component genuinely belongs on a secondary table, move the whole component under the corresponding <join> element instead of naming tables per column","After a rename, align every sub-attribute's table reference to one single table"],"exampleFix":"// before\n<component name='address' class='Address'>\n    <property name='street' column='street' table='user_addr'/>\n    <property name='city' column='city' table='addresses'/>\n</component>\n\n// after\n<component name='address' class='Address'>\n    <property name='street' column='street'/>\n    <property name='city' column='city'/>\n</component>","handlingStrategy":"validation","validationCode":"NodeList components = doc.getElementsByTagName(\"component\");\nfor (int i = 0; i < components.getLength(); i++) {\n    Set<String> tables = new HashSet<>();\n    NodeList children = components.item(i).getChildNodes();\n    for (int j = 0; j < children.getLength(); j++) {\n        if (children.item(j) instanceof Element e && e.hasAttribute(\"table\")) {\n            tables.add(e.getAttribute(\"table\"));\n        }\n    }\n    if (tables.size() > 1) {\n        throw new IllegalStateException(\"component columns span tables: \" + tables);\n    }\n}","typeGuard":null,"tryCatchPattern":"catch (MappingException e) at SessionFactory build; the message prints the component's attribute role and the two conflicting table names - remove or align the per-column table= attributes for that component.","preventionTips":["Never set table= on columns inside <component> unless the whole component targets that table","Put components that belong to a secondary table inside the matching <join>","Review column overrides after any table rename or entity refactor"],"tags":["hibernate","hbm-mapping","component","embedded","secondary-table"],"backgroundTag":"attribute-multi-table-mapping","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}