hibernate/hibernate-orm · error · UnsupportedOperationException
Unsupported foreign key part:
Error message
Unsupported foreign key part:
What it means
StructHelper.injectJdbcValue() decomposes aggregate-mapped (json/struct) embeddables into plain JDBC values for foreign-key handling. For a ToOneAttributeMapping it accepts only FK key parts that are BasicValuedMapping (single-column FK) or EmbeddableValuedModelPart (composite FK); any other key part throws UnsupportedOperationException('Unsupported foreign key part: <part>'). The mapped association's foreign key has a shape Hibernate cannot decompose in this path.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/type/descriptor/jdbc/StructHelper.java:247
attributeValues[attributeIndex],
ForeignKeyDescriptor.Nature.TARGET,
options.getSession()
);
if ( keyPart instanceof BasicValuedMapping ) {
jdbcValueCount = 1;
jdbcValues[jdbcIndex] = foreignKeyValue;
}
else if ( keyPart instanceof EmbeddableValuedModelPart embeddableValuedModelPart ) {
jdbcValueCount = injectJdbcValues(
embeddableValuedModelPart.getEmbeddableTypeDescriptor(),
foreignKeyValue,
jdbcValues,
jdbcIndex,
options
);
}
else {
throw new UnsupportedOperationException( "Unsupported foreign key part: " + keyPart );
}
}
else if ( attributeMapping instanceof PluralAttributeMapping ) {
return 0;
}
else if ( attributeMapping instanceof DiscriminatedAssociationAttributeMapping ) {
jdbcValueCount = attributeMapping.decompose(
attributeValues[attributeIndex],
jdbcIndex,
jdbcValues,
options,
(valueIndex, objects, wrapperOptions, value, jdbcValueMapping)
-> objects[valueIndex] = value,
options.getSession()
);
}
else if ( attributeMapping instanceof EmbeddableValuedModelPart embeddableValuedModelPart ) {
final EmbeddableMappingType embeddableMappingType = embeddableValuedModelPart.getMappedType();View on GitHub (pinned to fad1729dce)
Solutions
- Remove associations from the aggregate-mapped embeddable: represent the FK as a plain basic column (an id attribute with @Column) and map the @ManyToOne on the owning entity outside the aggregate.
- Split the embeddable so aggregate-mapped ones contain only basic and nested-embeddable parts.
- Check for a newer Hibernate release - support for association shapes in aggregate FK decomposition has changed across 6.x versions.
Example fix
// before: association inside the aggregate-mapped embeddable
@Embeddable public class OrderInfo {
String note;
@ManyToOne Customer customer; // FK key part is an aggregate -> unsupported
}
// after: keep the aggregate plain; move the association to the entity
@Embeddable public class OrderInfo {
String note;
Long customerId; // basic FK column
}
@Entity public class Order {
@Embedded OrderInfo info;
@ManyToOne @JoinColumn(name = "customer_id") Customer customer;
} Defensive patterns
Strategy: validation
Validate before calling
// At startup, assert aggregate embeddables contain only basic or embeddable parts
static void assertAggregateEmbeddableIsPlain(Class<?> embeddable) {
for (java.lang.reflect.Field f : embeddable.getDeclaredFields()) {
if (f.isAnnotationPresent(jakarta.persistence.ManyToOne.class)
|| f.isAnnotationPresent(jakarta.persistence.OneToOne.class)) {
throw new IllegalStateException(
embeddable.getName() + '.' + f.getName()
+ " is an association inside an aggregate-mapped embeddable - move it to the owning entity");
}
}
} Try / catch
try {
session.flush();
} catch (UnsupportedOperationException e) {
if (e.getMessage() != null && e.getMessage().startsWith("Unsupported foreign key part")) {
// message names the FK key part Hibernate cannot decompose:
// replace the embedded association with a basic FK column on the owning entity
} else {
throw e;
}
} Prevention
- Keep aggregate (json/struct) embeddables free of @ManyToOne/@OneToOne associations
- Represent FKs inside aggregates as plain id columns; map the association on the entity
- Re-test struct/json mappings on every Hibernate upgrade - aggregate FK support evolves
When it happens
Trigger: An aggregate (STRUCT/JSON) mapping whose embeddable contains a @ManyToOne/@OneToMany-side association whose foreign-key key part is neither basic nor embeddable valued - e.g., an association keyed by an aggregate/json id or another exotic part - hit during flush/decompose of the mapping.
Common situations: Embeddables shared between plain relational mappings and struct/json aggregate mappings that contain associations; porting Oracle/Postgres struct mappings; entity ids modeled as json aggregates; Hibernate version changes that made this helper path reachable for previously working mappings.
Related errors
- Unsupported foreign key part:
- Support for model part type not yet implemented:
- Struct not properly formed: {}
- Could not find selectable [%s] in embeddable type [%s] for J
- Can't parse JSON object for selectable [%s] which is not of
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/ecd051e9549f4f43.
Report an issue: GitHub.