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
相关产品推荐
相关产品推荐

