hibernate/hibernate-orm · error · UnsupportedOperationException
Composite key breakdown not yet implemented
Error message
Composite key breakdown not yet implemented
What it means
TableDescriptorAsTableMapping.breakDownKeyJdbcValues decomposes a key domain value into per-column JDBC values, but the adapter only implements the single-column case (keyColumns.size() == 1). A key spanning two or more columns - an @EmbeddedId/@IdClass composite key - throws UnsupportedOperationException instead of producing wrong SQL. It is an explicit 'not yet implemented' gap in the new action-queue meta layer, not a configuration error.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/action/queue/spi/meta/TableDescriptorAsTableMapping.java:118
@Override
public void forEachKeyColumn(KeyColumnConsumer consumer) {
for ( int i = 0; i < keyColumns.size(); i++ ) {
consumer.consume( i, keyColumns.get( i ) );
}
}
@Override
public void breakDownKeyJdbcValues(
Object domainValue,
KeyValueConsumer valueConsumer,
SharedSessionContractImplementor session) {
// For simple keys, the domain value is the JDBC value
// For composite keys, this would need more complex handling
if ( keyColumns.size() == 1 ) {
valueConsumer.consume( domainValue, keyColumns.get( 0 ) );
}
else {
throw new UnsupportedOperationException( "Composite key breakdown not yet implemented" );
}
}
@Override
public <K> DomainResult<K> createDomainResult(
NavigablePath navigablePath,
TableReference tableReference,
String resultVariable,
DomainResultCreationState creationState) {
throw new UnsupportedOperationException( "Domain result creation not needed for mutations" );
}
@Override
public int getJdbcTypeCount() {
return keyDescriptor.getJdbcTypeCount();
}
@OverrideView on GitHub (pinned to fad1729dce)
Solutions
- Introduce a single-column surrogate key (@Id @GeneratedValue) and demote the composite columns to a unique constraint.
- Until supported, run the affected persistence context with hibernate.flush.queue.type=legacy.
- Report/upvote composite-key support for the new queue in Hibernate JIRA with your mapping as a reproducer.
Example fix
// before @EmbeddedId private OrderLineId id; // 2 columns -> UnsupportedOperationException // after @Id @GeneratedValue private Long id; @Embeddable private OrderLineId naturalKey; // backed by a unique constraint
Defensive patterns
Strategy: validation
Validate before calling
// guard: composite keys are unsupported by the new queue's key breakdown
int keyCols = sessionFactory.getMappingMetamodel()
.getEntityDescriptor(entityClass)
.getIdentifierMapping()
.getJdbcTypeCount();
if (keyCols > 1) {
// use a surrogate key or hibernate.flush.queue.type=legacy
} Prevention
- Prefer single-column surrogate primary keys over natural composite keys
- Run an integration test that flushes every entity type before enabling the graph queue
- Watch Hibernate release notes for composite-key support in the new action queue
When it happens
Trigger: Flushing or mutating an entity (or table) whose key mapping resolves to 2+ key columns through code that calls breakDownKeyJdbcValues on this adapter - e.g. composite-key entities under the new graph-based flush machinery.
Common situations: Legacy schemas with natural composite primary keys; early adoption of Hibernate 8's incubating graph-based action queue whose mutation meta layer has not grown composite-key support yet.
Related errors
- Unsupported JdbcOperation type: %s
- Unbreakable unique update cycle detected for SCC: %s
- Unbreakable cycle detected for SCC: %s
- There are delayed insert actions before operation as cascade
- cannot recreate collection while filter is enabled: " + coll
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/d90f65680d68d51e.
Report an issue: GitHub.