hibernate/hibernate-orm · error · UnsupportedOperationException
Unsupported foreign key part:
Error message
Unsupported foreign key part:
What it means
Thrown while StructJdbcType unpacks raw JDBC values of a struct-typed aggregate column. When the embeddable mapped into the struct contains a to-one association, Hibernate reads the association's ForeignKeyDescriptor key part; only basic-valued (single-column FK) and embeddable-valued (composite FK) key parts are implemented. Any other key-part shape raises this explicit UnsupportedOperationException.
Source
Thrown at hibernate-core/src/main/java/org/hibernate/type/descriptor/jdbc/StructJdbcType.java:395
WrapperOptions options) throws SQLException {
final int numberOfAttributeMappings = embeddableMappingType.getNumberOfAttributeMappings();
for ( int i = 0; i < numberOfAttributeMappings + ( embeddableMappingType.isPolymorphic() ? 1 : 0 ); i++ ) {
final ValuedModelPart attributeMapping = getSubPart( embeddableMappingType, i );
if ( attributeMapping instanceof ToOneAttributeMapping toOneAttributeMapping ) {
if ( toOneAttributeMapping.getSideNature() == ForeignKeyDescriptor.Nature.TARGET ) {
continue;
}
final ValuedModelPart keyPart = toOneAttributeMapping.getForeignKeyDescriptor().getKeyPart();
if ( keyPart instanceof BasicValuedMapping ) {
wrapRawJdbcValue( keyPart.getSingleJdbcMapping(), jdbcValues, jdbcIndex, options );
jdbcIndex++;
}
else if ( keyPart instanceof EmbeddableValuedModelPart embeddableValuedModelPart ) {
final EmbeddableMappingType mappingType = embeddableValuedModelPart.getEmbeddableTypeDescriptor();
jdbcIndex = wrapRawJdbcValues( mappingType, jdbcValues, jdbcIndex, options );
}
else {
throw new UnsupportedOperationException( "Unsupported foreign key part: " + keyPart );
}
}
else if ( attributeMapping instanceof PluralAttributeMapping ) {
continue;
}
else if ( attributeMapping instanceof DiscriminatedAssociationAttributeMapping discriminatedMapping ) {
wrapRawJdbcValue(
discriminatedMapping.getDiscriminatorMapping()
.getSingleJdbcMapping(),
jdbcValues,
jdbcIndex,
options
);
jdbcIndex++;
wrapRawJdbcValue(
discriminatedMapping.getKeyPart().getSingleJdbcMapping(),
jdbcValues,
jdbcIndex,View on GitHub (pinned to fad1729dce)
Solutions
- Map the association's FK columns as plain basic attributes inside the embeddable instead of a @ManyToOne/@OneToOne.
- Move the association out of the struct-mapped embeddable onto the owning entity.
- Select the struct's component columns in the native query instead of the whole struct value.
- Upgrade Hibernate to a version supporting this key-part kind, or file an issue with a mapping that reproduces it.
Example fix
// before
@Embeddable
public class Address {
String street;
@ManyToOne // to-one inside a struct aggregate
Country country; // -> Unsupported foreign key part
}
// after
@Embeddable
public class Address {
String street;
@Column(name = "country_code")
String countryCode; // plain basic FK column instead
} Defensive patterns
Strategy: validation
Validate before calling
static void assertStructAggregateSafe(Class<?> embeddable) {
for (Field f : embeddable.getDeclaredFields()) {
if (f.isAnnotationPresent(ManyToOne.class) || f.isAnnotationPresent(OneToOne.class)
|| f.isAnnotationPresent(Any.class)) {
throw new IllegalStateException(
"Struct aggregate must not contain association: " + f
+ " (Unsupported foreign key part)");
}
}
} Try / catch
try {
return session.createNativeQuery("select address from users where id = :id", Address.class)
.setParameter("id", id).getSingleResult();
} catch (UnsupportedOperationException ex) {
if (ex.getMessage() != null && ex.getMessage().startsWith("Unsupported foreign key part")) {
throw new DataMappingException("Aggregate contains an unsupported association", ex);
}
throw ex;
} Prevention
- Keep struct and XML aggregates limited to basic attributes and nested embeddables.
- Cover struct reads with an integration test that selects the aggregate column before release.
- Review aggregate mappings after every Hibernate upgrade; FK part support changes between versions.
When it happens
Trigger: Reading a struct aggregate via StructJdbcType.extractJdbcValues (e.g. a native query selecting the struct column, or result mapping of an aggregate) where the embeddable has a @ManyToOne/@OneToone whose foreign-key key part is neither a BasicValuedMapping nor an EmbeddableValuedModelPart, e.g. derived-identity shapes (@ManyToOne @Id, @MapsId) where the key part is itself entity-valued.
Common situations: Modeling associations inside @Struct embeddables on Oracle OBJECT, PostgreSQL composite, or DB2 row types; upgrading Hibernate versions that introduced new FK part kinds; native queries returning the struct column directly instead of its components.
Related errors
- Unsupported foreign key part:
- Locking with joins is not supported
- No drop foreign key syntax supported by SQLiteDialect
- No add foreign key syntax supported by SQLiteDialect
- SingleStore does not support foreign keys and referential in
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/de3a4c33b7db7b3f.
Report an issue: GitHub.