Java开发过程中,常常会遇到一个对象中多次用到另一个对象的主键作为属性的情况。比如记录一个人的部门变化情况,需要同时记录变更前后的部门编号。之前有误区,以为在这种情况下的@JoinColumn属性必须是实体类的主键,而实际上这个注解的属性值是当前实体类的外键。举例如下:
首选创建Department实体类
@Entity @Table(name="department") public class Department implements Serializable{ private static final long serialVersionUID = 1L; private int departmentId; private String departmentName; @Id @GenerateValue @Column(name = "departmentId",nullable = false) public int getDepartmentId(){ return departmentId; } public void setDepartmentId(int departmentId) { this.departmentId = departmentId; } @Column(name = "departmentName",nullable = false) public int getDepartmentName(){ return departmentName; } public void setDepartmentName(String departmentName) { this.departmentName = departmentName; } }
和Employee实体类
@Entity @Table(name="employee") public class Employee implements Serializable{ private static final long serialVersionUID = 1L; private int employeetId; private String employeeName; @Id @GenerateValue @Column(name = "employeeId",nullable = false) public int getEmployeeId(){ return employeeId; } public void setEmployeeId(int employeeId) { this.employeeId = employeeId; } @Column(name = "employeeName",nullable = false) public int getEmployeeName(){ return employeeName; } public void setEmployeeName(String employeeName) { this.employeeName = employeeName; } }
接下来,创建用户的部门调动情况,实现如下:
@Entity @Table(name="empDeptChangeInfo") public class EmpDeptChangeInfo implements Serializable{ private static final long serialVersionUID = 1L; private int itemId; private Employee employee; private Department dept1; private Department dept2; @Id @GenerateValue @Column(name = "itemId",nullable = false) public int getItemId(){ return itemId; } public void setItemId(int itemId) { this.itemId = itemId; } @ManyToOne(cascade = CascadeType.REFRESH, optional = true) @JoinColumn(name = "employeeId") public int getEmployeeId(){ return employeeId; } public void setEmployee(Employee employee){ this.employee = employee; } @ManyToOne(cascade = CascadeType.REFRESH, optional = true) @JoinColumn(name = "deptId1") public getDept1(){ return dept1; } public void setDept1(Department dept1){ this.dept1 = dept1; } @ManyToOne(cascade = CascadeType.REFRESH, optional = true) @JoinColumn(name = "deptId2") public getDept2(){ return dept2; } public void setDept2(Department dept2){ this.dept2 = dept2; } }
值得注意的是,@JoinColumn后面的属性,并非所关联的表中定义的属性字段名或数据库名,如Dept1和Dept2在数据库表empDeptChangeInfo中对应的字段为deptId1和deptId2,而并不是department表的字段departmentId。