如何在JPA中为带不同EmbeddedId的类通过单列建立多对一关系?
仅通过复合主键中共有的字段建立JPA多对一关联的实现方法
可以仅通过两者共有的col_one字段建立关联,但原代码存在拼写错误和映射冲突问题,需要调整才能正确运行。
关键问题修正与映射方案
1. 修正基础拼写错误
原代码中@ManytoOne拼写错误,正确注解为@ManyToOne。
2. 避免主键字段重复维护
由于Class2的col_one已经是其复合主键Class2Id的一部分,直接映射@ManyToOne会导致JPA尝试重复维护该字段,引发冲突。推荐两种规范的解决方式:
方式一:使用@MapsId复用主键字段
这种方式明确告诉JPA,关联的col_one字段就是Class2复合主键的一部分,无需重复维护:
// Class2 修正后的代码 @Embeddable public class Class2Id { @Column(name = "col_one") String column1; @Column(name = "col_three") Integer column3; } @Entity public class Class2 { @EmbeddedId Class2Id class2Id; @ManyToOne @MapsId("column1") // 指定复用Class2Id中的column1属性(对应col_one列) @JoinColumn(name = "col_one", referencedColumnName = "col_one") Class1 class1; }
方式二:设置字段不可插入/更新
如果不想使用@MapsId,可以通过insertable = false, updatable = false让JPA仅通过复合主键维护col_one字段:
@Entity public class Class2 { @EmbeddedId Class2Id class2Id; @ManyToOne @JoinColumn( name = "col_one", referencedColumnName = "col_one", insertable = false, updatable = false ) Class1 class1; }
3. 确认Class1的映射正确性
Class1中的@OneToMany映射无需修改,mappedBy = "class1"可以正确关联到Class2中的关联字段:
@Entity public class Class1 { @EmbeddedId Class1Id class1Id; @OneToMany(mappedBy = "class1") List<Class2> class2List; }
总结
即使两个实体的复合主键结构不同,只要存在共有的字段(如col_one),就可以基于该字段建立多对一/一对多关联。核心是避免主键字段的重复维护,推荐使用@MapsId的方式实现更规范的映射。
内容的提问来源于stack exchange,提问作者장재영
相关产品推荐
相关产品推荐

