hibernate/hibernate-orm · error · MappingException

Encountered multiple component mappings for the same java cl

Error message

Encountered multiple component mappings for the same java class {embeddableClassName} with different property mappings. Every property mapping combination should have its own java class

What it means

A MappingException raised by MetadataContext.locateEmbeddable during JPA metamodel/bootstrap processing when the same embeddable Java class is encountered in two component mappings that declare different numbers of properties. Hibernate keys embeddable domain types by Java class; a cached Component for that class with a different property span (cachedComponentPropertySpan != component.getPropertySpan()) proves the class is being mapped with inconsistent attribute sets, which the JPA model cannot represent, so bootstrap fails demanding one Java class per property-mapping combination.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/metamodel/internal/MetadataContext.java:901

	}

	public EmbeddableDomainType<?> locateEmbeddable(Class<?> embeddableClass, Component component) {
		final var domainType = embeddables.get( embeddableClass );
		if ( domainType != null ) {
			return domainType;
		}
		else {
			final var embeddableDomainTypes = embeddablesToProcess.get( embeddableClass );
			if ( embeddableDomainTypes != null ) {
				for ( var embeddableDomainType : embeddableDomainTypes ) {
					final var cachedComponent = componentByEmbeddable.get( embeddableDomainType );
					if ( cachedComponent.isSame( component ) ) {
						return embeddableDomainType;
					}
					else if ( cachedComponent.getComponentClass().equals( component.getComponentClass() ) ) {
						final int cachedComponentPropertySpan = cachedComponent.getPropertySpan();
						if ( cachedComponentPropertySpan != component.getPropertySpan() ) {
							throw new MappingException( "Encountered multiple component mappings for the same java class "
											+ embeddableClass.getName() +
											" with different property mappings. Every property mapping combination should have its own java class" );
						}
						else {
							for ( int i = 0; i < cachedComponentPropertySpan; i++ ) {
								if ( !cachedComponent.getProperty( i ).getName()
										.equals( component.getProperty( i ).getName() ) ) {
									throw new MappingException( "Encountered multiple component mappings for the same java class "
													+ embeddableClass.getName() +
													" with different property mappings. Every property mapping combination should have its own java class" );
								}
							}
						}
						return embeddableDomainType;
					}
					else {
						throw new MappingException( "Encountered multiple component mappings for the same java class "
										+ embeddableClass.getName() +

View on GitHub (pinned to fad1729dce)

Solutions

  1. Give each distinct property combination its own Java class (extract a smaller record/class for the subset mapping)
  2. Make every mapping of that embeddable declare exactly the same property list (same names, same order, same count)
  3. If only column names differ, keep the attribute set identical and use @AttributeOverrides/@Column to change just the columns
  4. Verify with sessionFactory.getMetamodel() in a smoke test that both mappings can coexist at boot

Example fix

<!-- before - same class, different property counts -->
<component name="home" class="Address">
    <property name="street" column="HOME_STREET"/>
    <property name="city" column="HOME_CITY"/>
</component>
<component name="billing" class="Address">
    <property name="street" column="BILL_STREET"/>
    <!-- city omitted -->
</component>

<!-- after - same attribute set everywhere (columns may differ) -->
<component name="billing" class="Address">
    <property name="street" column="BILL_STREET"/>
    <property name="city" column="BILL_CITY"/>
</component>
Defensive patterns

Strategy: validation

Validate before calling

// Assert every mapping of an embeddable class declares the same attribute set
Map<Class<?>, Set<List<String>>> byClass = new HashMap<>();
for ( Mapping m : allComponentMappings() ) {
    byClass.computeIfAbsent(m.getComponentClass(), k -> new HashSet<>()).add(m.attributeNamesInOrder());
}
for ( var e : byClass.entrySet() ) {
    if ( e.getValue().size() > 1 ) {
        throw new IllegalStateException("Embeddable " + e.getKey() + " mapped with different attribute sets: " + e.getValue());
    }
}

Try / catch

try {
    EntityManagerFactory emf = Persistence.createEntityManagerFactory("pu");
}
catch ( org.hibernate.mapping.MappingException e ) {
    if ( e.getMessage() != null && e.getMessage().contains("multiple component mappings for the same java class") ) {
        throw new ConfigurationError("Split the embeddable into one class per property-mapping combination - " + e.getMessage(), e);
    }
    throw e;
}

Prevention

When it happens

Trigger: Two entities embedding the same class where one mapping lists a subset of the fields (e.g. hbm.xml <component> blocks each enumerating different <property> lists); one mapping applying @AttributeOverrides/@Transient-style exclusions so the persisted attribute set differs; XML components generated by different teams for the same class.

Common situations: Legacy hbm.xml components reusing one class with per-mapping property lists; mappings where a field was added to the embeddable and only one of several embedding mappings was updated; annotation mappings using different column/attribute subsets of a shared embeddable.

Related errors


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