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。