JPA - @OneToMany 更新

发布于 2024-12-20 04:08:19 字数 947 浏览 2 评论 0原文

考虑有两个实体:部门和员工,其中一个部门有 N 名员工。

在部门中:

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

在员工中:

@ManyToOne(fetch = FetchType.EAGER)
private Department department;

一切正常,但我想将员工添加到部门而不设置反向关系。例如:

// 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);      
//...

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

department.getEmployees().add(employee1);
department.getEmployees().add(employee2);
entityManager.merge(department);

非常感谢!

Consider that there are two entities, Department and Employee, where in one department there are N employees.

In Departament:

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

In Employee:

@ManyToOne(fetch = FetchType.EAGER)
private Department department;

Everything works, but I would like to add employees to the department without set the inverse relationship. For example:

// 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);      
//...

So, my question is: is there some way (eg. by some annotation) that the JPA will understand that it should propagate the changes to the other side of the relationship without I explicit that? In other words, I would like to do only this:

department.getEmployees().add(employee1);
department.getEmployees().add(employee2);
entityManager.merge(department);

Thanks a lot!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

和影子一齐双人舞 2024-12-27 04:08:19

明确的答案是:不,您的 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;
  }
}

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

The clear answer is: No, it is not possible that your JPA provider can automatically handle bidirectional relations they way you described it.

You can however implement the logic for setting bidirectional associations in your entities, maybe something along these lines:

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;
  }
}

In this case you must however ensure that the associations are already initialized when the entities are handled outside the persistence context to avoid lazy init exceptions. This might force you to switch to eager loading for all associations, which is generally not a good choice.
Due to the complexity of bidirectional associations I personally avoid bidirectional associations in entities and only use them when there are really good reasons for it.

一张白纸 2024-12-27 04:08:19

JPA 不会为您管理您的 java 对象图。您可以像在问题中那样自行更新对象图,或者我想您可能可以在保存后重新加载所有实体。

我不喜欢双向关系,因为它们可能会变得混乱,但如果你必须这样做,那么你可能会想要选择一侧作为关系的“拥有”一侧。查找此页面上有关“mappedBy”的位置 http://www.objectdb.com /java/jpa/entity/fields 了解如何执行此操作的信息。

如果您已经实现了一项服务,那么您可以提供一个服务调用来负责管理此类内容,那么您就不会有很大的机会将其忘记在代码中的某个位置并正确执行在其他15个地方。

JPA is not going to manage your java Object graph for you. You can either update the object graph yourself as you do in your question, or I guess you could probably reload all the entities after saving.

I'm not a fan of bidirectional relationships because they can get messy, but if you must do it then you will probably want to select one side to be the "owning" side of the relationship. Look for where it talks about "mappedBy" on this page http://www.objectdb.com/java/jpa/entity/fields for information on how to do that.

If you have a service that you have implemented, then you could provide a service call that takes care of managing this kind of stuff, then you won't have as great a chance of forgetting it in one place in your code and doing it correctly in the other 15 places.

懷念過去 2024-12-27 04:08:19

正如您提到的,执行此操作的唯一方法是明确的。

The only way to do this is explicitly, like you mentioned.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文