hibernate/hibernate-orm · error · MappingException

collection id mapping has wrong number of columns: " + getRo

Error message

collection id mapping has wrong number of columns: " + getRole() + " type: " + getIdentifier().getType().getName()

What it means

IdentifierCollection#validate checks the surrogate id mapping of an idbag collection (<idbag> / @CollectionId) and throws when the id Value is not valid - in practice its column span does not match the declared type, for example a multi-column type used as the collection id.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/mapping/IdentifierCollection.java:79

			&& isSame( identifier, other.identifier );
	}

	void createPrimaryKey() {
		if ( !isOneToMany() ) {
			final var primaryKey = new PrimaryKey( getCollectionTable() );
			primaryKey.addColumns( getIdentifier() );
			getCollectionTable().setPrimaryKey( primaryKey );
		}
		// create an index on the key columns??
	}

	public void validate(MappingContext mappingContext) throws MappingException {
		super.validate( mappingContext );

		assert getElement() != null : "IdentifierCollection identifier not bound : " + getRole();

		if ( !getIdentifier().isValid( mappingContext ) ) {
			throw new MappingException(
				"collection id mapping has wrong number of columns: " +
				getRole() +
				" type: " +
				getIdentifier().getType().getName()
			);
		}
	}
}

View on GitHub (pinned to fad1729dce)

Solutions

  1. Give the collection id a single-column basic type (long, or UUID stored as one column) with an explicit @Column.
  2. Declare the generator explicitly on @CollectionId (e.g. a sequence generator) so the id resolves cleanly.
  3. Where possible replace legacy idbags with a normal @ElementCollection plus @OrderColumn, or promote the bag to an owning entity row.

Example fix

// before - multi-column type as collection id
@CollectionId(
    columns = @Column(name = "bag_id"),
    type = @Type(StringArrayType.class),
    generator = "seq"
)
Collection<String> tags;

// after - single-column basic type
@CollectionId(
    columns = @Column(name = "bag_id"),
    type = @Type(LongType.class),
    generator = "seq"
)
Collection<String> tags;
Defensive patterns

Strategy: try-catch

Try / catch

try {
    metadata = sources.buildMetadata();
} catch (MappingException e) {
    // message contains the collection role + id type name - inspect the
    // @CollectionId / <collection-id> of that role
    throw e;
}

Prevention

When it happens

Trigger: A @CollectionId whose type maps to more than one column; an hbm <collection-id> whose type/column combination does not resolve; forgetting the @Column for the collection id; using an array or composite type as the bag id.

Common situations: Legacy idbag mappings migrated between Hibernate versions; introducing custom types into @CollectionId; hand-editing hbm <idbag> elements.

Related errors


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