You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Hibernate如何映射关联另一复合主键的复合主键实体

Hibernate 复合主键关联复合主键的正确映射方案

报错的核心原因是Role实体使用包含siteId、id两个字段的复合主键CommonId,因此关联Role时需要两个列才能定位唯一实例,而原有映射只提供了role_id一个列,导致Hibernate校验不通过。


修改方案

1. 无需调整的代码

UserSiteRoleId嵌入式主键定义完全符合表结构,可以保留原有逻辑:

@Embeddable
public class UserSiteRoleId implements Serializable {

    @Type(type = "pg-id-uuid")
    @Column(columnDefinition = "uuid", updatable = false)
    private UUID userId;

    @Type(type = "pg-id-uuid")
    @Column(name = "site_id", columnDefinition = "uuid", updatable = false)
    private UUID siteId;

    @Type(type = "pg-id-uuid")
    @Column(name = "role_id", columnDefinition = "uuid", updatable = false)
    private UUID roleId;
}

2. 调整UserSiteRole实体的Role关联逻辑

核心修改点是用@JoinColumns指定双外键映射,复用已有的site_id字段避免重复映射:

@Entity
@Table(name = "user_site_roles", schema = "core")
@Data
@TypeDefs({
        @TypeDef(name = "pg-id-uuid", typeClass = PostgresIdUUIDType.class)
})
public class UserSiteRole extends AuditCreated implements Serializable {

    @EmbeddedId
    private UserSiteRoleId userSiteRoleId;

    @ManyToOne
    @MapsId("userId")
    @JoinColumn(name = "user_id", columnDefinition = "uuid", nullable = false)
    @OnDelete(action = OnDeleteAction.CASCADE)
    private User user;

    @ManyToOne
    @MapsId("siteId")
    @JoinColumn(name = "site_id", columnDefinition = "uuid", nullable = false)
    @OnDelete(action = OnDeleteAction.CASCADE)
    private Site site;

    // 仅修改Role关联部分即可
    @ManyToOne
    @MapsId("roleId")
    @JoinColumns(value = {
            @JoinColumn(name = "site_id", referencedColumnName = "site_id", insertable = false, updatable = false),
            @JoinColumn(name = "role_id", referencedColumnName = "id", nullable = false)
    })
    @OnDelete(action = OnDeleteAction.CASCADE)
    private Role role;

}

关键说明

  • 用@JoinColumns指定两个外键列,完全匹配外键约束user_site_roles_role_id_fkey的定义,对应roles表的复合主键
  • site_id列已经被Site关联的@MapsId("siteId")映射,因此设置insertable = false, updatable = false避免重复映射冲突
  • 持久化UserSiteRole实例时,只需正常赋值site、user、role属性,Hibernate会自动填充UserSiteRoleId的三个主键字段,无需手动设置
  • 你提供的user_site_roles建表脚本中,user_id外键定义末尾缺少逗号,执行前需要补充修正,避免建表失败

内容的提问来源于stack exchange,提问作者arkhadi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 07:54:05