hibernate/hibernate-orm · error · MappingException

Attribute [%s] referenced columns from multiple tables: %s,

Error message

Attribute [%s] referenced columns from multiple tables: %s, %s

What it means

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.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/boot/model/source/internal/hbm/ModelBinder.java:1368

	private Identifier determineTable(
			MappingDocument sourceDocument,
			String attributeName,
			RelationalValueSourceContainer relationalValueSourceContainer) {
		return determineTable( sourceDocument, attributeName,
				relationalValueSourceContainer.getRelationalValueSources() );
	}

	private Identifier determineTable(
			MappingDocument mappingDocument,
			SingularAttributeSourceEmbedded embeddedAttributeSource) {
		Identifier tableName = null;
		for ( var attributeSource : embeddedAttributeSource.getEmbeddableSource().attributeSources() ) {
			final Identifier determinedName =
					determineTableName( mappingDocument, embeddedAttributeSource, attributeSource );
			if ( determinedName != null && !determinedName.equals( tableName ) ) {
				if ( tableName != null ) {
					throw new MappingException(
							"Attribute [%s] referenced columns from multiple tables: %s, %s"
									.formatted( embeddedAttributeSource.getAttributeRole().getFullPath(),
											tableName, determinedName ),
							mappingDocument.getOrigin()
					);
				}
				tableName = determinedName;
			}
		}
		return tableName;
	}

	private Identifier determineTableName(MappingDocument mappingDocument, SingularAttributeSourceEmbedded embeddedAttributeSource, AttributeSource attributeSource) {
		if ( attributeSource instanceof RelationalValueSourceContainer relationalValueSourceContainer ) {
			return determineTable(
					mappingDocument,
					embeddedAttributeSource.getAttributeRole().getFullPath(),
					relationalValueSourceContainer

View on GitHub (pinned to fad1729dce)

Solutions

  1. Remove the explicit table= attributes from the component's sub-attribute columns so they all default to the containing table
  2. If the component genuinely belongs on a secondary table, move the whole component under the corresponding <join> element instead of naming tables per column
  3. After a rename, align every sub-attribute's table reference to one single table

Example fix

// before
<component name='address' class='Address'>
    <property name='street' column='street' table='user_addr'/>
    <property name='city' column='city' table='addresses'/>
</component>

// after
<component name='address' class='Address'>
    <property name='street' column='street'/>
    <property name='city' column='city'/>
</component>
Defensive patterns

Strategy: validation

Validate before calling

NodeList components = doc.getElementsByTagName("component");
for (int i = 0; i < components.getLength(); i++) {
    Set<String> tables = new HashSet<>();
    NodeList children = components.item(i).getChildNodes();
    for (int j = 0; j < children.getLength(); j++) {
        if (children.item(j) instanceof Element e && e.hasAttribute("table")) {
            tables.add(e.getAttribute("table"));
        }
    }
    if (tables.size() > 1) {
        throw new IllegalStateException("component columns span tables: " + tables);
    }
}

Try / catch

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.

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22). Data as JSON: /api/errors/8bbe546ff74953ca. Report an issue: GitHub.