hibernate/hibernate-orm · error · MappingException

Identity generation requires a column

Error message

Identity generation requires a column

What it means

Hibernate throws this MappingException from SimpleValue.setColumnToIdentity() when an identity id generator is applied to a value whose single column slot is not an actual Column (e.g. a Formula or some other KeyValue column object). Identity generation relies on the database auto-increment feature, so it needs exactly one real, physical column it can mark as IDENTITY. A formula or virtual column cannot be auto-generated by the database.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/mapping/SimpleValue.java:457

				setNullValueUndefined();
			}
			return generator;
		}
		else {
			return null;
		}
	}

	@Internal
	public void setColumnToIdentity() {
		if ( getColumnSpan() != 1 ) {
			throw new MappingException( "Identity generation requires exactly one column" );
		}
		else if ( getColumn(0) instanceof Column column ) {
			column.setIdentity( true );
		}
		else {
			throw new MappingException( "Identity generation requires a column" );
		}
	}

	@Override
	public boolean isUpdateable() {
		//needed to satisfy KeyValue
		return true;
	}

	@Override
	public FetchStyle getFetchStyle() {
		return FetchStyle.SELECT;
	}

	@Override
	public Table getTable() {
		return table;
	}

View on GitHub (pinned to fad1729dce)

Solutions

  1. Remove any <formula> or virtual/non-Column definition from the identifier property so it maps exactly one physical column.
  2. If the key really is computed, switch the generator away from IDENTITY (e.g. to @GeneratedValue(strategy = GenerationType.SEQUENCE) or no generator) since a formula cannot be identity-generated.
  3. In hbm.xml, verify the <id> element contains only a single <column> child and no <formula> child.
  4. For programmatic models, assert SimpleValue.getColumn(0) is an org.hibernate.mapping.Column before the generator is bound.

Example fix

// before (hbm.xml)
<id name="id">
    <formula>NEXT_VALUE('seq')</formula>
    <generator class="identity"/>
</id>

// after
<id name="id">
    <column name="id"/>
    <generator class="native"/>
</id>
Defensive patterns

Strategy: validation

Validate before calling

// before binding an identity generator to a programmatic SimpleValue
if ( value.getColumnSpan() == 1 && value.getColumn(0) instanceof Column col ) {
    value.setColumnToIdentity(); // safe
}
else {
    throw new IllegalStateException("id is not backed by exactly one physical Column; cannot use IDENTITY");
}

Try / catch

try {
    metadata.buildMetadata().buildSessionFactory();
} catch (MappingException e) {
    if (e.getMessage().contains("Identity generation requires")) {
        throw new IllegalStateException("ID mapping must map exactly one physical column (no formulas) for IDENTITY generation: " + e.getMessage(), e);
    }
    throw e;
}

Prevention

When it happens

Trigger: Applying @GeneratedValue(strategy = GenerationType.IDENTITY) (or <generator class="identity"/>) to an id whose SimpleValue maps a formula, a <formula> element in hbm.xml, or a column object that is not org.hibernate.mapping.Column; also programmatic models where a non-Column value is set as the single column of an identity-generated SimpleValue.

Common situations: hbm.xml mappings that mix <column> and <formula> on the id property; legacy mappings migrated between Hibernate versions where the id column was replaced by a formula; programmatic (boot) model builders that assign a virtual column to an identity id; dialects that force identity generation while the mapping declares a computed key.

Related errors


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