hibernate/hibernate-orm · error · MappingException

must specify an identifier type: %s

Error message

must specify an identifier type: %s

What it means

Hibernate binds an <id> element in hbm.xml into a BasicValue and must end up with a concrete type. The type comes either from an explicit type attribute or from reflecting on the mapped class property named by name=. When the id has no explicit type and reflection is impossible (name missing, or the entity has no POJO representation such as dynamic-map entity-name mappings), binding aborts with this MappingException.

Source

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

	private void bindSimpleEntityIdentifier(
			MappingDocument sourceDocument,
			final EntityHierarchySource hierarchySource,
			RootClass rootEntityDescriptor) {
		final var idSource = (IdentifierSourceSimple) hierarchySource.getIdentifierSource();

		final var idValue = new BasicValue( sourceDocument, rootEntityDescriptor.getTable() );
		rootEntityDescriptor.setIdentifier( idValue );

		bindSimpleValueType(
				sourceDocument,
				idSource.getIdentifierAttributeSource().getTypeInformation(),
				idValue
		);

		final String propertyName = idSource.getIdentifierAttributeSource().getName();
		if ( propertyName == null || !rootEntityDescriptor.hasPojoRepresentation() ) {
			if ( !idValue.isTypeSpecified() ) {
				throw new MappingException(
						"must specify an identifier type: " + rootEntityDescriptor.getEntityName(),
						sourceDocument.getOrigin()
				);
			}
		}
		else {
			idValue.setTypeUsingReflection( rootEntityDescriptor.getClassName(), propertyName );
		}

		final var identifierAttributeSource =
				(RelationalValueSourceContainer)
						idSource.getIdentifierAttributeSource();
		relationalObjectBinder.bindColumnsAndFormulas(
				sourceDocument,
				identifierAttributeSource.getRelationalValueSources(),
				idValue,
				false,
				context -> {

View on GitHub (pinned to fad1729dce)

Solutions

  1. Add an explicit type attribute to the <id> element, e.g. <id name='id' type='long'>
  2. If the entity is a normal POJO, give <id> a name attribute matching an actual field/getter so Hibernate can resolve the type by reflection
  3. For dynamic-map entities (entity-name without class), an explicit type on <id> is mandatory - add it

Example fix

// before
<class entity-name='User' table='users'>
    <id name='id'>
        <generator class='native'/>
    </id>
</class>

// after
<class entity-name='User' table='users'>
    <id name='id' type='long'>
        <generator class='native'/>
    </id>
</class>
Defensive patterns

Strategy: validation

Validate before calling

// before build: scan every <class> that has entity-name but no class, and every <id>
NodeList ids = doc.getElementsByTagName("id");
for (int i = 0; i < ids.getLength(); i++) {
    Element id = (Element) ids.item(i);
    boolean hasType = id.getAttributeNode("type") != null;
    boolean hasName = id.getAttributeNode("name") != null;
    Element owner = (Element) id.getParentNode();
    boolean isPojo = owner.getAttributeNode("class") != null;
    if (!hasType && (!hasName || !isPojo)) {
        throw new IllegalStateException("<id> needs an explicit type: " + owner.getAttribute("entity-name"));
    }
}

Try / catch

catch (MappingException e) during bootstrap; the message names the entity whose id lacks a type. Add type= to that entity's <id> and rebuild.

Prevention

When it happens

Trigger: <class entity-name='...' ...> (non-POJO / dynamic-map entity) with an <id> lacking a type attribute; an <id> element with no name attribute and no type; a template-generated mapping where type='long' was dropped.

Common situations: Dynamic-model entities (entity-name only, no class) where reflection cannot supply the type; hand-written or generator-produced hbm.xml files; migrations where the explicit type attribute got lost.

Related errors


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