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
- Give the identifier a property: <id name="id" column="ID"> with a matching Java field, or map it as <composite-id name="..." class="...">
- If the id genuinely has no attribute, declare it as a proper composite (Component) so the JPA metamodel can enumerate its attributes
- Prefer JPA annotations (@Id/@EmbeddedId/@IdClass) for new mappings to avoid this legacy corner
- 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
- Always bind identifiers to a property (name=) in XML or use @Id annotations
- Lint legacy hbm.xml files before running them under the JPA (EntityManagerFactory) bootstrap
- Prefer @EmbeddedId/@IdClass annotations for composite ids instead of hand-written XML
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
- Attribute was not a Map : ${collectionMemberType}
- Unable to create AttributeConverter instance
- Property '${path}' specifies ${columnCount} '@AttributeOverr
- Secondary table '${explicitTableName}' for property '${prope
- Column mappings for property '${propertyName}' mix nullable
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/33427644cc46286f.
Report an issue: GitHub.