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

JPA中单向OneToMany关联与复合主键配置问题

解决JPA复合主键(parent_id + application)的实现方案

步骤1:定义复合主键类

创建@Embeddable类型的复合主键类,包含parentId和application两个字段,同时实现Serializable接口(JPA强制要求):

@Embeddable
data class ChildId(
    val parentId: Long,
    val application: String
) : Serializable

步骤2:修改ChildEntity实体

用@EmbeddedId替换原来的单一@Id,将复合主键作为实体的主键,移除原有的单独application字段:

@Entity(name = "child")
data class ChildEntity(
    @EmbeddedId
    val id: ChildId,

    @Column(name = "tag")
    val tag: String? = null
)

步骤3:调整ParentEntity的关联关系

修改@OneToMany注解,通过mappedBy关联到子实体主键中的parentId字段,同时添加orphanRemoval = true实现“更新时先删再存”的需求:

@Entity(name = "parent")
data class ParentEntity(
    @Id
    var id: Long? = null,

    @OneToMany(
        mappedBy = "id.parentId",
        cascade = [CascadeType.ALL],
        fetch = FetchType.LAZY,
        orphanRemoval = true
    )
    var children: MutableList<ChildEntity> = mutableListOf()
)

关键说明

  • 复合主键ChildId保证了child表的主键是(parent_id, application),解决了相同application无法属于不同父实体的问题。
  • orphanRemoval = true会自动删除父实体中不再包含的子实体,配合CascadeType.ALL,插入时会全量保存所有子实体,刚好匹配你“插入全量保存、更新先删再存”的需求。
  • 移除了原@JoinColumn中的unique = true配置,该配置会错误限制一个父实体只能有一个子实体,现在通过复合主键实现正确的唯一性约束。
  • 使用MutableList而非List,方便业务层更新子实体列表,确保Hibernate能正确检测到集合变化。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 08:43:41