hibernate/hibernate-orm · error · MappingException

identifier mapping has wrong number of columns: " +…

Error message

identifier mapping has wrong number of columns: " + getEntityName() + " type: " + getIdentifier().getType().getName()

What it means

Root-class validation found the identifier mapping invalid: getIdentifier().isValid(mapping) returned false for the id Value of a root entity. Like the column-span check for normal properties, but specific to the identifier: the id type's required column count disagrees with the mapped columns, or the id Value is otherwise invalid.

Solutions

  1. For composite ids, map exactly one column per key property (one @EmbeddedId field per column, or one key-property entry per column in hbm)
  2. Verify the id type's column span matches the mapped column count
  3. Avoid formulas in identifiers; map real columns instead

Example fix

// before
<composite-id class="OrderId">
  <key-property name="tenantId"/>
  <key-property name="seq"/>  <!-- OrderId maps only tenantId to a column -->
</composite-id>

// after
<!-- make OrderId map both tenantId and seq to real columns -->
Defensive patterns

Strategy: validation

Validate before calling

for (PersistentClass pc : metadata.getEntityBindings()) {
    if (pc instanceof RootClass root && !root.getIdentifier().isValid((Mapping) metadata)) {
        // identifier column count mismatch; fix the id mapping before bootstrap
    }
}

Try / catch

try { metadata.buildSessionFactory(); }
catch (MappingException e) {
    if (e.getMessage().contains("identifier mapping has wrong number of columns")) {
        // align the composite id components with the mapped columns
    }
    throw e;
}

Prevention

When it happens

Trigger: An @EmbeddedId whose component columns do not match the embeddable's properties; an id assigned a custom type spanning multiple columns while only one column is mapped; hbm composite-id with key-property lists that do not align; formulas used inside the identifier.

Common situations: Changing an id from simple to composite (or back) without updating columns; legacy hbm composite ids after a schema change; custom UserType identifiers after a Hibernate upgrade.

Related errors


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

Appendix: source

Thrown at hibernate-core/src/main/java/org/hibernate/mapping/RootClass.java:281

	public void setConcreteProxy(boolean concreteProxy) {
		this.concreteProxy = concreteProxy;
	}

	@Override
	public String getWhere() {
		return where;
	}

	public void setWhere(String string) {
		where = string;
	}

	@Override
	public void validate(Metadata mapping) throws MappingException {
		super.validate( mapping );
		if ( !getIdentifier().isValid( mapping ) ) {
			throw new MappingException(
					"identifier mapping has wrong number of columns: " +
							getEntityName() +
							" type: " +
							getIdentifier().getType().getName()
			);
		}
		checkCompositeIdentifier();
		checkTableDuplication();
	}

	/**
	 * In {@linkplain jakarta.persistence.InheritanceType#SINGLE_TABLE single table}
	 * inheritance, subclasses share a table with the root class by definition. But
	 * for {@linkplain jakarta.persistence.InheritanceType#JOINED joined} or
	 * {@linkplain jakarta.persistence.InheritanceType#TABLE_PER_CLASS union} mappings,
	 * the subclasses are assumed to occupy distinct tables, and it's an error to map
	 * two subclasses to the same table.
	 * <p>

View on GitHub (pinned to fad1729dce)