JPA - @OneToMany更新

joa*_*vio 6 annotations hibernate jpa one-to-many

考虑到有两个实体,即部门和员工,其中一个部门有N个员工.

在Departament:

@OneToMany(mappedBy = "department", fetch = FetchType.EAGER)
private Collection<Employee> employees = new ArrayList<Employee>();
Run Code Online (Sandbox Code Playgroud)

在员工中:

@ManyToOne(fetch = FetchType.EAGER)
private Department department;
Run Code Online (Sandbox Code Playgroud)

一切正常,但我想在没有设置反向关系的情况下将员工添加到部门.例如:

// I will add two employees to a department
department.getEmployees().add(employee1);
department.getEmployees().add(employee2);

// In fact, it is necessary to set the opposite side of the relationship
employee1.setDepartment(department);
employee2.setDepartment(department);

entityManager.merge(department);      
//...
Run Code Online (Sandbox Code Playgroud)

所以,我的问题是:是否有某种方式(例如通过一些注释)JPA会理解它应该将更改传播到关系的另一端而不是我明确的那样?换句话说,我只想这样做:

department.getEmployees().add(employee1);
department.getEmployees().add(employee2);
entityManager.merge(department);
Run Code Online (Sandbox Code Playgroud)

非常感谢!

tsc*_*cho 3

明确的答案是:不,您的 JPA 提供程序不可能按照您所描述的方式自动处理双向关系。

然而,您可以实现在实体中设置双向关联的逻辑,也许是这样的:

class Department {

  public void addEmployee(Employee empl) {
    if (empl.getDepartment() != null && !this.equals(empl.getDepartment())) {
      empl.getDepartment().getEmployees().remove(empl);
    }
    empl.setDepartment(this); // use the plain setter without logic
    this.employees.add(empl);
  }
}


class Employee {
  // additional setter method with logic
  public void doSetDepartment(Department dept) {
    if (this.department != null && !this.department.equals(dept)) {
      this.department.getEmployees().remove(this);
    }
    dept.getEmployees().add(this);
    this.department = dept;
  }
}
Run Code Online (Sandbox Code Playgroud)

然而,在这种情况下,您必须确保在持久化上下文之外处理实体时关联已经初始化,以避免延迟初始化异常。这可能会迫使您切换到所有关联的预先加载,这通常不是一个好的选择。由于双向关联的复杂性,我个人避免在实体中使用双向关联,并且仅在确实有充分理由时才使用它们。