首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >配置Hibernate注释以管理历史记录集合的最佳方法是什么?

配置Hibernate注释以管理历史记录集合的最佳方法是什么?
EN

Stack Overflow用户
提问于 2020-05-11 23:18:58
回答 1查看 38关注 0票数 0

我有一个案例,除了雇员实体和轮班实体之间的@OneToMany关系之外,我还有一对@OneToOne关系。员工有一个Current Shift,一个Last ,以及一个Shift集合,它们表示员工执行过的轮班的历史记录。下面的代码显示了如何设置hibernate注释来表示这一点。

代码语言:javascript
复制
@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;
}
代码语言:javascript
复制
@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;
}

这里有一些示例代码来说明我想要做的事情。

代码语言:javascript
复制
   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:

目前看来一切都很好..。

代码语言:javascript
复制
   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。任何帮助都将不胜感激。

谢谢!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-05-19 01:43:31

我能够通过从Employee类中删除@JoinColumn(name = "EMP_ID")并使用mappedBy relationship属性来获得我想要的行为。

代码语言:javascript
复制
@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;
}
代码语言:javascript
复制
@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属性,我可以指定关系将由逆实体管理。这对我的案子很管用。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61741083

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档