hibernate/hibernate-orm · error · MappingException

Identity generation requires exactly one column

Error message

Identity generation requires exactly one column

What it means

setColumnToIdentity() requires the value to map exactly one real column. Identity-based generation (auto-increment) works only on a single column, so a value spanning zero or multiple columns (composite ids, formula-only ids) is rejected. It usually surfaces while binding @GeneratedValue(strategy = IDENTITY).

Source

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

			GeneratorSettings defaults) {
		if ( customIdGeneratorCreator != null ) {
			final var context = new IdGeneratorCreationContext( this, rootClass, property, defaults );
			final var generator = customIdGeneratorCreator.createGenerator( context );
			GeneratorTypeHelper.checkGeneratorGeneratedType( generator, context );
			if ( generator.allowAssignedIdentifiers() && nullValue == null ) {
				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;

View on GitHub (pinned to fad1729dce)

Solutions

  1. Use a single-column id with IDENTITY generation
  2. For composite ids, use assigned identifiers or a surrogate key with a table/sequence generator
  3. If the id was meant to be simple, remove the extra key columns or formulas

Example fix

// before
@EmbeddedId
@GeneratedValue(strategy = GenerationType.IDENTITY)
private OrderId id; // OrderId spans 2 columns

// after
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
Defensive patterns

Strategy: validation

Validate before calling

if (pc instanceof RootClass root) {
    Value id = root.getIdentifier();
    boolean singleRealColumn = id.getColumnSpan() == 1
            && id.getColumns().get(0) instanceof Column;
    if (!singleRealColumn && usesIdentityGeneration(root)) {
        // IDENTITY cannot be used; switch the generator strategy before binding
    }
}

Prevention

When it happens

Trigger: @GeneratedValue(strategy = GenerationType.IDENTITY) on an @EmbeddedId or composite key spanning multiple columns; an id mapping built from a formula instead of a column; an hbm identity generator class on a multi-column id.

Common situations: Switching an entity from a simple to a composite id while keeping IDENTITY; database-first generated mappings; copy-pasting generator settings between simple and composite ids.

Related errors


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