【发布时间】:2020-08-27 15:58:51
【问题描述】:
我有一个案例,除了 Employee 实体和 Shift 实体之间的 @OneToMany 关系之外,我还有几个 @OneToOne 关系。员工有一个Current Shift、一个Last Shift,以及一组Shifts,它们代表该员工所执行的班次的历史记录。下面的代码显示了我如何设置我的休眠注释来表示这一点。
@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 班与我的员工失去了关联。我知道,由于我正在执行合并,其中只有 Shifts 4-6 在班次列表中,所以休眠正在更新数据库以仅映射这 3 个班次而其他班次变得孤立,但我真正想要的是保持数据库中的那些历史记录。我想可以做到这样的事情;我只是没有做冬眠的权利。任何帮助将不胜感激。
谢谢!
【问题讨论】:
-
你能分享你的服务代码吗?
-
@Ricardo 我已经用代码示例更新了我的帖子,我认为这将有助于说明我正在尝试做的事情。谢谢!
标签: hibernate collections merge one-to-many many-to-one