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

Hibernate中如何创建指向复合主键的一对多关联关系?

解决方案:Deck.entries的映射调整

推荐方案:双向关联(符合JPA规范)

这种方式能让Hibernate清晰识别复合主键与外键的关联关系,避免多余SQL操作:

1. 调整DeckEntry类,添加Deck关联并绑定主键字段

在DeckEntry中新增@ManyToOne关联到Deck,用@MapsId注解把这个关联和嵌入主键里的deckID字段绑定:

@Entity
public class DeckEntry {
    
    @EmbeddedId
    private DeckEntryID id;

    @ManyToOne
    @MapsId("deckID") // 关联嵌入主键中的deckID字段
    @JoinColumn(name = "deckID", nullable = false)
    private Deck deck;

    @Column(nullable = false)
    private int cardCount;

    // 构造方法、getter/setter、hashCode和equals(基于id实现)
}

2. 修改Deck类的entries字段,指定关联反向端

在Deck的@OneToMany注解里加mappedBy,指向DeckEntry里的deck属性:

@Entity
public class Deck {

   @Id
   private UUID id;

   @Column(name = "name", nullable = false)
   private String name;

   @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, mappedBy = "deck")
   private Set<DeckEntry> entries;

   // 构造方法、getter/setter、hashCode和equals(基于id实现)
}

关键说明

  • @MapsId("deckID")明确告诉Hibernate:DeckEntry的外键列deckID不仅是关联Deck的字段,同时也是复合主键的组成部分,解决了核心的映射关联问题。
  • mappedBy = "deck"指定Deck是关联关系的主控端,DeckEntry负责维护外键,避免生成多余的更新语句。

备选方案:单向关联(无需修改DeckEntry)

如果不想搞双向关联,直接修改Deck类的entries字段即可:

@Entity
public class Deck {

   @Id
   private UUID id;

   @Column(name = "name", nullable = false)
   private String name;

   @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
   @JoinColumn(name = "deckID", referencedColumnName = "id", nullable = false)
   private Set<DeckEntry> entries;

   // 构造方法、getter/setter、hashCode和equals(基于id实现)
}

这种方式直接通过deckID列关联两张表,但保存Deck时可能会多执行一次更新语句,所以优先推荐双向关联方案。

内容的提问来源于stack exchange,提问作者Martin Häusler

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 14:58:13