{"record":{"id":"ecd051e9549f4f43","repo":"hibernate/hibernate-orm","slug":"unsupported-foreign-key-part","errorCode":null,"errorMessage":"Unsupported foreign key part: ","messagePattern":"Unsupported foreign key part: ","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/type/descriptor/jdbc/StructHelper.java","lineNumber":247,"sourceCode":"\t\t\t\t\tattributeValues[attributeIndex],\n\t\t\t\t\tForeignKeyDescriptor.Nature.TARGET,\n\t\t\t\t\toptions.getSession()\n\t\t\t);\n\t\t\tif ( keyPart instanceof BasicValuedMapping ) {\n\t\t\t\tjdbcValueCount = 1;\n\t\t\t\tjdbcValues[jdbcIndex] = foreignKeyValue;\n\t\t\t}\n\t\t\telse if ( keyPart instanceof EmbeddableValuedModelPart embeddableValuedModelPart ) {\n\t\t\t\tjdbcValueCount = injectJdbcValues(\n\t\t\t\t\t\tembeddableValuedModelPart.getEmbeddableTypeDescriptor(),\n\t\t\t\t\t\tforeignKeyValue,\n\t\t\t\t\t\tjdbcValues,\n\t\t\t\t\t\tjdbcIndex,\n\t\t\t\t\t\toptions\n\t\t\t\t);\n\t\t\t}\n\t\t\telse {\n\t\t\t\tthrow new UnsupportedOperationException( \"Unsupported foreign key part: \" + keyPart );\n\t\t\t}\n\t\t}\n\t\telse if ( attributeMapping instanceof PluralAttributeMapping ) {\n\t\t\treturn 0;\n\t\t}\n\t\telse if ( attributeMapping instanceof DiscriminatedAssociationAttributeMapping ) {\n\t\t\tjdbcValueCount = attributeMapping.decompose(\n\t\t\t\t\tattributeValues[attributeIndex],\n\t\t\t\t\tjdbcIndex,\n\t\t\t\t\tjdbcValues,\n\t\t\t\t\toptions,\n\t\t\t\t\t(valueIndex, objects, wrapperOptions, value, jdbcValueMapping)\n\t\t\t\t\t\t\t-> objects[valueIndex] = value,\n\t\t\t\t\toptions.getSession()\n\t\t\t);\n\t\t}\n\t\telse if ( attributeMapping instanceof EmbeddableValuedModelPart embeddableValuedModelPart ) {\n\t\t\tfinal EmbeddableMappingType embeddableMappingType = embeddableValuedModelPart.getMappedType();","sourceCodeStart":229,"sourceCodeEnd":265,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/type/descriptor/jdbc/StructHelper.java#L229-L265","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before: association inside the aggregate-mapped embeddable\n@Embeddable public class OrderInfo {\n    String note;\n    @ManyToOne Customer customer; // FK key part is an aggregate -> unsupported\n}\n\n// after: keep the aggregate plain; move the association to the entity\n@Embeddable public class OrderInfo {\n    String note;\n    Long customerId; // basic FK column\n}\n@Entity public class Order {\n    @Embedded OrderInfo info;\n    @ManyToOne @JoinColumn(name = \"customer_id\") Customer customer;\n}","handlingStrategy":"validation","validationCode":"// At startup, assert aggregate embeddables contain only basic or embeddable parts\nstatic void assertAggregateEmbeddableIsPlain(Class<?> embeddable) {\n    for (java.lang.reflect.Field f : embeddable.getDeclaredFields()) {\n        if (f.isAnnotationPresent(jakarta.persistence.ManyToOne.class)\n                || f.isAnnotationPresent(jakarta.persistence.OneToOne.class)) {\n            throw new IllegalStateException(\n                embeddable.getName() + '.' + f.getName()\n                + \" is an association inside an aggregate-mapped embeddable - move it to the owning entity\");\n        }\n    }\n}","typeGuard":null,"tryCatchPattern":"try {\n    session.flush();\n} catch (UnsupportedOperationException e) {\n    if (e.getMessage() != null && e.getMessage().startsWith(\"Unsupported foreign key part\")) {\n        // message names the FK key part Hibernate cannot decompose:\n        // replace the embedded association with a basic FK column on the owning entity\n    } else {\n        throw e;\n    }\n}","preventionTips":["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"],"tags":["hibernate","aggregate-mapping","struct","foreign-key","embeddable","association"],"backgroundTag":"unsupported-association-mapping","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}