我有一个案例,除了雇员实体和轮班实体之间的@OneToMany关系之外,我还有一对@OneToOne关系。员工有一个Current Shift,一个Last ,以及一个Shift集合,它们表示员工执行过的轮班的历史记录。下面的代码显示了如何设置hibernate注释来表示这一点。
@Entity
public class Employee {
@Id
@Column(name = "EMP_ID")
private Long id;
@OneToOne(cascade = {CascadeType.ALL})
@JoinColumn(name = "CURRENT_SHIFT_ID")
private Shift currentShift;
@OneToOne(cascade = {CascadeType.ALL})
@JoinColumn(name = "LAST_SHIFT_ID")
private Shift lastShift;
@OneToMany(fetch = FetchType.LAZY, cascade = {CascadeType.ALL})
@JoinColumn(name = "EMP_ID")
private List<Shift> shifts;
}@Entity
public class Shift {
@Id
@Column(name = "SHIFT_ID")
private Long id;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "EMP_ID", nullable = false)
private Employee employee;
@Column(name = "START_DATE")
private Calendar startDate;
@Column(name = "END_DATE")
private Calendar endDate;
}这里有一些示例代码来说明我想要做的事情。
public void test1(long employeeId) {
Employee dbEmployee = entityManager.find(Employee.class, employeeId);
Calendar startDate = Calendar.getInstance();
Calendar endDate = Calendar.getInstance();
// create the first shift
Shift one = new Shift();
one.setEmployee(dbEmployee);
one.setStartDate(startDate);
one.setEndDate(endDate);
// create the second shift
Shift two = new Shift();
two.setEmployee(dbEmployee);
two.setStartDate(startDate);
two.setEndDate(endDate);
// create the third shift
Shift three = new Shift();
three.setEmployee(dbEmployee);
three.setStartDate(startDate);
three.setEndDate(endDate);
// add shifts 1-3 to the collection of shifts that the employee just performed
List<Shift> shifts = new ArrayList<Shift>();
shifts.add(one);
shifts.add(two);
shifts.add(three);
dbEmployee.setShifts(shifts);
// set the last shift to shift #2
dbEmployee.setLastShift(two);
// set the current shift to shift #3
dbEmployee.setCurrentShift(three);
entityManager.merge(dbEmployee);
}在上面的Test1方法中,除了指定哪个轮班是员工的最后一次轮班和当前轮班之外,我还要为员工创建轮班1-3,并填充轮班集合。当我对雇员执行合并时,生成的数据库表如下所示:
员工表
id: 1,currentShiftId: 3,lastShiftId: 2
移位表
id: 1,employeeId: 1,startDate:.,endDate:
id: 2,employeeId: 1,startDate:.,endDate:
id: 3,employeeId: 1,startDate:.,endDate:
目前看来一切都很好..。
public void test2(long employeeId) {
Employee dbEmployee = entityManager.find(Employee.class, employeeId);
Calendar startDate = Calendar.getInstance();
Calendar endDate = Calendar.getInstance();
// create the fourth shift
Shift four = new Shift();
four.setEmployee(dbEmployee);
four.setStartDate(startDate);
four.setEndDate(endDate);
// create the fifth shift
Shift five = new Shift();
five.setEmployee(dbEmployee);
five.setStartDate(startDate);
five.setEndDate(endDate);
// create the sixth shift
Shift six = new Shift();
six.setEmployee(dbEmployee);
six.setStartDate(startDate);
six.setEndDate(endDate);
// add shifts 4-6 to the collection of shifts that the employee just performed
List<Shift> shifts = new ArrayList<Shift>();
shifts.add(four);
shifts.add(five);
shifts.add(six);
dbEmployee.setShifts(shifts);
// set the last shift to shift #5
dbEmployee.setLastShift(five);
// set the current shift to shift #6
dbEmployee.setCurrentShift(six);
entityManager.merge(dbEmployee);
}但是,当我执行上面创建移位4-6的Test2方法并对员工执行合并时,结果是:
员工表
id: 1,currentShiftId: 6,lastShiftId: 5
移位表
id: 1,employeeId: NULL,startDate:…,endDate:.
id: 2,employeeId: NULL,startDate:.,endDate:
id: 3,employeeId: NULL,startDate:.,endDate:
id: 4,employeeId: 1,startDate:.,endDate:
id: 5,employeeId: 1,startDate:.,endDate:
id: 6,employeeId: 1,startDate:.,endDate:
所以轮班1-3正和我的员工脱节。我了解到,由于我正在执行一个合并,其中只有4-6移动在轮班列表中,hibernate正在更新数据库,使其只映射这3种转移,而其他的则成为孤儿,但我真正想要的是将这些历史记录保存在数据库中。我想这样的事情是可以做的,我只是没有正确地做hibernate。任何帮助都将不胜感激。
谢谢!
发布于 2020-05-19 01:43:31
我能够通过从Employee类中删除@JoinColumn(name = "EMP_ID")并使用mappedBy relationship属性来获得我想要的行为。
@Entity
public class Employee {
@Id
@Column(name = "EMP_ID")
private Long id;
@OneToOne(cascade = {CascadeType.ALL})
@JoinColumn(name = "CURRENT_SHIFT_ID")
private Shift currentShift;
@OneToOne(cascade = {CascadeType.ALL})
@JoinColumn(name = "LAST_SHIFT_ID")
private Shift lastShift;
@OneToMany(fetch = FetchType.LAZY, cascade = {CascadeType.ALL}, mappedBy = "employee")
//@JoinColumn(name = "EMP_ID") // this will try to manage the relationship
private List<Shift> shifts;
}@Entity
public class Shift {
@Id
@Column(name = "SHIFT_ID")
private Long id;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "EMP_ID", nullable = false)
private Employee employee;
@Column(name = "START_DATE")
private Calendar startDate;
@Column(name = "END_DATE")
private Calendar endDate;
}我的新理解是,当您希望@JoinColumn注释管理该关系时,将使用该注释。相反,通过使用mappedBy属性,我可以指定关系将由逆实体管理。这对我的案子很管用。
https://stackoverflow.com/questions/61741083
复制相似问题