hibernate/hibernate-orm · error · MappingException

Struct [%s] is defined by multiple components %s but some co

Error message

Struct [%s] is defined by multiple components %s but some columns are missing in [%s]: %s

What it means

Final stage of validateEqual: every column of one definition of a struct must exist in the other definition. Columns present in udt1 with no counterpart in udt2 are collected and reported in this MappingException, which lists the struct name, the component classes, and the missing columns.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/boot/model/internal/AggregateComponentSecondPass.java:426

			if ( column2 == null ) {
				missingColumns.add( column1 );
			}
			else if ( !column1.getSqlType().equals( column2.getSqlType() ) ) {
				throw new MappingException(
						String.format(
								"Struct [%s] of class [%s] is defined by multiple components with different mappings [%s] and [%s] for column [%s]",
								udt1.getName(),
								componentClassDetails.getName(),
								column1.getSqlType(),
								column2.getSqlType(),
								column1.getCanonicalName()
						)
				);
			}
		}

		if ( !missingColumns.isEmpty() ) {
			throw new MappingException(
					String.format(
							"Struct [%s] is defined by multiple components %s but some columns are missing in [%s]: %s",
							udt1.getName(),
							findComponentClasses(),
							componentClassDetails.getName(),
							missingColumns
					)
			);
		}
	}

	private TreeSet<String> findComponentClasses() {
		final TreeSet<String> componentClasses = new TreeSet<>();
		context.getMetadataCollector().visitRegisteredComponents(
				c -> {
					if ( component.getStructName().equals( c.getStructName() ) ) {
						componentClasses.add( c.getComponentClassName() );
					}

View on GitHub (pinned to fad1729dce)

Solutions

  1. Add the missing columns to the incomplete component so both map the identical column set
  2. Or remove the extra columns from the richer component
  3. Best: replace both with one canonical embeddable class for that struct
  4. If the mappings are intentionally different, change the struct name of one

Example fix

// before: struct A maps 2 columns, struct B (same name) misses 'zip'
@Embeddable @Struct(name = "address")
public class FullAddress { String street; String zip; }

@Embeddable @Struct(name = "address")
public class ShortAddress { String street; }   // 'zip' missing -> error

// after: identical column sets
@Embeddable @Struct(name = "address")
public class FullAddress { String street; String zip; }

@Embeddable @Struct(name = "address")
public class ShortAddress { String street; @Column(name = "zip") String zipCode; } // aligned
Defensive patterns

Strategy: validation

Validate before calling

// Before boot: assert identical effective column-name sets per struct name
static boolean columnSetsMatch(Class<?> a, Class<?> b) {
    Set<String> namesA = columnMap(a).keySet();
    Set<String> namesB = columnMap(b).keySet();
    return namesA.equals(namesB);
}

Try / catch

try {
    sessionFactory = metadata.buildSessionFactory();
} catch (MappingException e) {
    if (e.getMessage().contains("some columns are missing")) {
        throw new IllegalStateException("Struct components map different column sets", e);
    }
    throw e;
}

Prevention

When it happens

Trigger: Two components share a @Struct(name=...) where one maps extra fields/columns the other lacks - overlapping-but-not-identical field sets (the count check passed after one side dropped fields, but names still diverge).

Common situations: Removing a field from one of two duplicated struct embeddables; partial refactors of a shared UDT model; merging modules where two Address-like embeddables ended up with the same struct name.

Related errors


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