Hibernate中复合外键关联场景下如何配置POJO的映射规则?
Hibernate复合主键与复合外键映射配置方案
1 定义Table1的联合主键类
Hibernate要求联合主键必须单独封装为独立类,同时满足三个规则:实现java.io.Serializable接口、重写equals()和hashCode()方法、提供无参构造方法。
import java.io.Serializable; import java.util.Objects; public class Table1Id implements Serializable { // 字段类型和实际表字段类型保持一致即可 private String col1; private String col2; public Table1Id() {} public Table1Id(String col1, String col2) { this.col1 = col1; this.col2 = col2; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Table1Id table1Id = (Table1Id) o; return Objects.equals(col1, table1Id.col1) && Objects.equals(col2, table1Id.col2); } @Override public int hashCode() { return Objects.hash(col1, col2); } // 实际使用时需补充getter、setter方法 }
2 定义Table1主实体类
使用@IdClass注解绑定联合主键类,两个主键字段单独标记@Id注解:
import javax.persistence.*; @Entity @Table(name = "table1") @IdClass(Table1Id.class) public class Table1 { @Id @Column(name = "col1") private String col1; @Id @Column(name = "col2") private String col2; @Column(name = "col3") private String col3; @Column(name = "col4") private String col4; // 可选配置:如果需要从Table1侧关联查询关联的Table2记录可以添加 @OneToMany(mappedBy = "table1", cascade = CascadeType.ALL) private List<Table2> table2List; // 实际使用时需补充无参构造、getter、setter方法 }
3 定义Table2实体类配置复合外键
使用@JoinColumns注解批量配置关联的外键字段,分别对应Table1的两个主键字段:
import javax.persistence.*; @Entity @Table(name = "table2") public class Table2 { // 此处以c3为单主键示例,若Table2无单独主键,可同样用c1、c2作为联合主键 @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "c3") private String c3; @Column(name = "c4") private String c4; // 配置多对一关联+复合外键 @ManyToOne @JoinColumns(value = { @JoinColumn(name = "c1", referencedColumnName = "col1"), @JoinColumn(name = "c2", referencedColumnName = "col2") }) private Table1 table1; // 实际使用时需补充无参构造、getter、setter方法 }
可选:传统XML映射配置
如果项目使用XML格式配置映射,可参考以下配置示例
table1.hbm.xml
<class name="com.example.Table1" table="table1"> <composite-id class="com.example.Table1Id"> <key-property name="col1" column="col1"/> <key-property name="col2" column="col2"/> </composite-id> <property name="col3" column="col3"/> <property name="col4" column="col4"/> <!-- 一对多关联配置 --> <set name="table2List" mapped-by="table1"> <key> <column name="c1"/> <column name="c2"/> </key> <one-to-many class="com.example.Table2"/> </set> </class>
table2.hbm.xml
<class name="com.example.Table2" table="table2"> <id name="c3" column="c3"> <generator class="native"/> </id> <property name="c4" column="c4"/> <!-- 多对一复合外键配置 --> <many-to-one name="table1" class="com.example.Table1"> <column name="c1"/> <column name="c2"/> </many-to-one> </class>
注意事项
- 联合主键类的字段类型、名称要和实体类中标记
@Id的字段完全对应 @JoinColumn的name属性是当前表(table2)的外键字段名,referencedColumnName是关联表(table1)的主键字段名,不要写反- 如果Table2本身需要用c1、c2作为联合主键,可以在Table2类上同样添加
@IdClass注解,将c1、c2标记为@Id即可
内容的提问来源于stack exchange,提问作者Harshit Vijayvargia
相关产品推荐
相关产品推荐

