hibernate/hibernate-orm · error · MappingException
Cannot use identity column key generation with <union-subcla
Error message
Cannot use identity column key generation with <union-subclass> mapping for: %s
What it means
TABLE_PER_CLASS inheritance (union-subclass) answers polymorphic queries with UNION over the concrete class tables, which cannot produce meaningful results if each table independently assigns primary keys via the database IDENTITY mechanism. UnionSubclassEntityPersister.validateGenerator() therefore rejects IdentityGenerator at SessionFactory boot with a MappingException naming the entity.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/persister/entity/UnionSubclassEntityPersister.java:219
getIdentifierMapping(),
tableName,
getIdentifierColumnNames()
)
);
visitAttributeMappings( (attribute) -> {
builder.addAttribute( attribute );
attribute.forEachSelectable( (selectableIndex, selectable)
-> builder.addColumn( attribute, ColumnDescriptor.from( selectable ) ) );
} );
// Union subclass has only one table, so entity-wide flag equals table flag
return new EntityTableDescriptor[] { builder.build( builder.isSelfReferential ) };
}
protected void validateGenerator() {
if ( getGenerator() instanceof IdentityGenerator ) {
throw new MappingException( "Cannot use identity column key generation with <union-subclass> mapping for: " + getEntityName() );
}
}
@Override
public boolean containsTableReference(String tableExpression) {
for ( String subclassTableExpression : subclassTableExpressions ) {
if ( subclassTableExpression.equals( tableExpression ) ) {
return true;
}
}
return false;
}
@Override
public UnionTableReference createPrimaryTableReference(
SqlAliasBase sqlAliasBase,
SqlAstCreationState creationState) {View on GitHub (pinned to fad1729dce)
Solutions
- Switch to a shared generator: @GeneratedValue(strategy = SEQUENCE) with @SequenceGenerator on the root
- Use a TABLE generator, UUID strategy, or assigned identifiers if the database has no sequences
- If IDENTITY columns are mandatory, switch the hierarchy to JOINED inheritance instead
- Avoid generator class "native" on identity-only dialects - pin the strategy explicitly
Example fix
// before
@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public class Vehicle {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY) // rejected
Long id;
}
// after
@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public class Vehicle {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "veh_seq")
@SequenceGenerator(name = "veh_seq", sequenceName = "vehicle_seq", allocationSize = 50)
Long id;
} Defensive patterns
Strategy: validation
Validate before calling
// fail fast in CI: TABLE_PER_CLASS + IDENTITY is rejected by Hibernate
for (Class<?> e : entityClasses) {
Inheritance inh = e.getAnnotation(Inheritance.class);
GeneratedValue gv = e.getAnnotation(GeneratedValue.class);
if (inh != null && inh.strategy() == InheritanceType.TABLE_PER_CLASS
&& gv != null && gv.strategy() == GenerationType.IDENTITY) {
throw new IllegalStateException("TABLE_PER_CLASS + IDENTITY not supported: " + e.getName());
}
} Try / catch
try { sessionFactory = cfg.buildSessionFactory(); } catch (MappingException e) { if (e.getMessage().contains("identity column key generation")) { /* switch the hierarchy to SEQUENCE/TABLE/UUID generation */ } throw e; } Prevention
- Default new hierarchies to SEQUENCE generation; reserve IDENTITY for non-inherited tables
- Never rely on generator class 'native' for union-subclass mappings on identity-only databases
- Add a config-scan test for the TABLE_PER_CLASS + IDENTITY combination
When it happens
Trigger: @Inheritance(strategy = TABLE_PER_CLASS) with @GeneratedValue(strategy = GenerationType.IDENTITY) on the root identifier; hbm.xml <union-subclass> with <generator class="native"/> on a dialect where native resolves to identity (MySQL, SQL Server); dialect-native generation picking identity implicitly.
Common situations: Porting an app from SINGLE_TABLE to TABLE_PER_CLASS on MySQL where auto-increment was used; generated mappings defaulting to IDENTITY; using database auto-increment columns out of habit on union hierarchies.
Related errors
- Couldn't find table reference
- Identifier property '" + getPath( holder, data ) + "' cannot
- Attribute '%s' of entity '%s' is mapped by association '%s'
- Identifier attribute '%s' of entity '%s' has type '%s' but i
- Attribute '%s' of entity '%s' is mapped by association '%s'
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/01a5758ae30a0989.
Report an issue: GitHub.