hibernate/hibernate-orm · error · MappingException

Expecting Component for id mapping with no id-attribute

Error message

Expecting Component for id mapping with no id-attribute

What it means

A org.hibernate.mapping.MappingException thrown by MetadataContext while populating the JPA metamodel for an entity that has no id attribute (persistentClass.getIdentifierProperty() == null). In that situation Hibernate expects a non-aggregated composite id, i.e. persistentClass.getIdentifier() must be a Component; when the identifier is some other kind of value (for example an <id> mapping without a name/property, producing a bare SimpleValue), the JPA metamodel step aborts with this error during EntityManagerFactory/SessionFactory creation.

Source

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

						(SingularPersistentAttribute<T, ?>)
								buildAttribute( declaredIdentifierProperty, identifiableType,
										this::buildIdAttribute );
				attributeContainer.getInFlightAccess().applyIdAttribute( idAttribute );
			}
			else {
				final var superclassIdentifier = getMappedSuperclassIdentifier( persistentClass );
				if ( superclassIdentifier != null && superclassIdentifier.isGeneric() ) {
					// If the superclass identifier is generic, we have to build the attribute to register the concrete type
					final var concreteIdentifier =
							buildIdAttribute( identifiableType, persistentClass.getIdentifierProperty() );
					attributeContainer.getInFlightAccess().addConcreteGenericAttribute( concreteIdentifier );
				}
			}
		}
		else {
			// we have a non-aggregated composite-id
			if ( !( persistentClass.getIdentifier() instanceof Component compositeId ) ) {
				throw new MappingException( "Expecting Component for id mapping with no id-attribute" );
			}

			applyIdAttributes( persistentClass, identifiableType, compositeId );
		}
	}

	private <T> void applyIdAttributes(
			PersistentClass persistentClass,
			IdentifiableDomainType<T> identifiableType,
			Component compositeId) {
		assert compositeId.isEmbedded();
		// Handle the actual id attributes
		final var identifierMapper = persistentClass.getIdentifierMapper();
		final var idClassType =
				identifierMapper == null || identifierMapper.getComponentClassName() == null
						? null  // support for no @IdClass, especially for dynamic models
						: applyIdClassMetadata( (Component) persistentClass.getIdentifier() );
		final var id = identifierMapper == null ? compositeId : identifierMapper;

View on GitHub (pinned to fad1729dce)

Solutions

  1. Give the identifier a property: <id name="id" column="ID"> with a matching Java field, or map it as <composite-id name="..." class="...">
  2. If the id genuinely has no attribute, declare it as a proper composite (Component) so the JPA metamodel can enumerate its attributes
  3. Prefer JPA annotations (@Id/@EmbeddedId/@IdClass) for new mappings to avoid this legacy corner
  4. Validate all hbm.xml id declarations before switching from native to JPA bootstrap

Example fix

<!-- before - id without a property: JPA metamodel fails -->
<class name="User" table="USERS">
    <id column="USER_ID">
        <generator class="assigned"/>
    </id>
</class>

<!-- after - id bound to an attribute -->
<class name="User" table="USERS">
    <id name="id" column="USER_ID">
        <generator class="assigned"/>
    </id>
</class>
public class User { private Long id; ... }
Defensive patterns

Strategy: validation

Validate before calling

// Static check over hbm.xml before JPA bootstrap: every <id> must bind a property
Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(hbmFile);
NodeList ids = doc.getElementsByTagName("id");
for (int i = 0; i < ids.getLength(); i++) {
    Element id = (Element) ids.item(i);
    if ( !id.hasAttribute("name") ) {
        throw new IllegalStateException("<id> without 'name' in " + hbmFile + " breaks JPA metamodel building");
    }
}

Try / catch

try {
    EntityManagerFactory emf = Persistence.createEntityManagerFactory("pu");
}
catch ( org.hibernate.mapping.MappingException e ) {
    if ( "Expecting Component for id mapping with no id-attribute".equals(e.getMessage()) ) {
        throw new ConfigurationError("An <id>/<composite-id> mapping lacks a bound id attribute - add name/class", e);
    }
    throw e;
}

Prevention

When it happens

Trigger: Legacy hbm.xml mappings with <id column="..."> that declare no 'name' attribute (no id property) while JPA metamodel population is active; dynamic-map or map-mode entities whose composite id is not built as a Component; mapping combinations produced by hand-edited or generated XML where the identifier ends up as a simple value with no corresponding attribute.

Common situations: Maintaining old Hibernate 3/4-style hbm.xml mappings that predate property-based id declarations; running the JPA bootstrap (EntityManagerFactory) over mappings originally written for native SessionFactory usage; migration tooling that drops attributes while reshaping id mappings.

Related errors


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