Spring Boot:如何使用存储库分别保持一对多关系

时间:2018-08-09 09:11:57

标签: spring hibernate spring-boot spring-data-jpa

我有两个班,分别是部门雇员。他们之间的关系是一对多,即一个部门可以有很多员工。

没有部门就不能存在员工。
部门可以有0到n名员工。

我同时获得这两个项目的列表...这些列表可以包含新条目和更新条目。

我的问题是,我该怎么办?

  1. 独立保存/合并部门
  2. 在第1步之后独立保存/合并员工(确保该员工的部门ID在部门表中存在)

OR

  1. 要与Set<>名员工一起保存/合并部门吗?

OR

还有没有想到的另一种方法吗?

3 个答案:

答案 0 :(得分:3)

有两种模式,分别称为“存储库”和“聚合”,它们来自Eric Evans Domain Driven Design 书,最好的方法是使用其中一种。

存储库模式

  • 两个独立的实体(部门和员工)
  • 实体之间没有JPA关系(@OneToMany
  • employee仅包含它的departmentId字段
  • 两个存储库(departmentRepoemployeeRepo

如果您必须设立员工部门,则应为:

department = departmentRepo.findById(employee.departmentId)

保存实体还独立使用其存储库:

newDepartment = departmentRepo.save(new Department())
newEmployee = employeeRepo.save(new Employee(newDepartment.id))

聚合模式

与两个存储库不同,并且实体之间没有连接,这会导致聚合模式的使用:

  • 一个存储库(在这种情况下为departmentRepo
  • department实体与@OneToManyemployees连接(部门包含员工)。

在这种情况下,要获取员工,您必须使用部门存储库:

employees = departmentRepo.findById(departmentId).employees

要保存的内容相同:您应该保存部门以保存员工中的更改。

回顾

这些模式的任何混合使用(最常见的是:两个存储库和实体之间的JPA关系)在将来会导致真正难以维护的问题。

在大多数情况下,我更喜欢存储库模式:每个实体的存储库,并且实体之间没有关系。

在您的情况下,我会选择存储库模式。

答案 1 :(得分:3)

您可以定义如下的实体类:

@Entity
public class Department {
  @NotNull
  @Id
  private String depId;
  private String depName;

  @OneToMany(mappedBy = "department", cascade = CascadeType.ALL, fetch = FetchType.LAZY,
  orphanRemoval = true)
  private Set<Employee> employees;
}

@Entity
public class Employee {

  @Id
  private String employeeId;
  private String employeeName;
  @ManyToOne
  @JoinColumn(name = "dep_id", nullable = true)
  private Department department;
}

保留部门的员工和部门员工可以为空。您需要在这些实体上定义存储库才能获取/保存。 另外,如果要使用一组雇员,请确保它覆盖对象类的hashcode()和equals()方法。

答案 2 :(得分:0)

您应该在员工类中有一个Department字段。每当您更改员工与部门之间的关联时,都需要设置employee.department,并将该员工添加到对应的department.employees集合中,或从中删除该员工。

然后,仅假设为Department.employees集合正确设置了CascadeType,就需要保存部门。