JPA 更新双向关联



假设我们有以下实体:

    @Entity
    public class Department {
        @OneToMany(mappedBy="department")
        private List<Employee> employees;
    }
    @Entity
    public class Employee {
        @ManyToOne
        private Department department
    }

在更新中可以理解,我们需要保持关系的双方,如下所示:

Employee emp = new Employee();
Department dep = new Department();
emp.setDepartment(dep);
dep.getEmployees().add(emp);

到目前为止一切都很好。问题是我是否应该按如下方式在两侧应用合并,并且我是否应该避免使用级联进行第二次合并?

entityManager.merge(emp);
entityManager.merge(dep);

还是合并拥有方就足够了?此外,这些合并是否应该在事务或 EJB 中进行?还是在具有分离实体的简单控制器方法上执行此操作就足够了?

问题是我是否

应该按如下方式在两侧应用合并,并且我是否应该避免使用级联进行第二次合并?

可以使用级联注释元素将操作的效果传播到关联的实体。级联功能最常用于父子关系。

如果这些关系已使用 cascade 元素值cascade=MERGEcascade=ALL注释进行了批注,则merge操作将级联到Department关系引用的实体。

托管实体之间的双向关系将根据关系的拥有方(Employee)持有的引用进行保留。开发人员有责任使保存在拥有端的内存中引用(Employee)和在反向侧保存的内存中引用在更改时(Department)彼此一致。因此,通过以下一系列语句,关系将通过单个merge同步到数据库:

Employee emp = new Employee();
Department dep = new Department();
emp.setDepartment(dep);
dep.getEmployees().add(emp);
...
entityManager.merge(dep);

这些更改将在事务提交时传播到数据库。当事务处于活动状态时,也可以使用 EntityManager#flush 方法将实体的内存中状态同步到数据库。

你有一个持久操作(用em.merge() (。保留新员工并不意味着该部门也保留(您没有级联(,因此它会因为其他原因而引发异常(只需尝试并发布异常(。为了避免这种情况,您可以添加级联类型,或者同时保留它们(如示例中所做的那样(。

关于你的问题:唯一考虑的部分是拥有方。在 JPA 2.0 规范中,Chapter 3 Entity Operations => 3.2.4 Syncrhonization to the Database 如下:

托管实体之间的双向关系将保持不变 基于关系的拥有方持有的参考资料。是的 开发人员有责任保留内存中的引用 在拥有方和持有的反方一致 彼此改变时。在单向一对一的情况下 和一对多关系,这是开发商的责任 以确保遵守关系的语义。[注二九]

与事务的需要有关:是的,合并操作需要活动事务。摘自 JPA 2 规范:

必须在 当实体经理具有 使用事务范围的持久性上下文。如果没有 交易上下文, javax.persistence.TransactionRequiredException 被抛出。

关于交易的开始方式/你如何盯着交易:这取决于EntityManager的类型(你如何获得交易的方式(。在 EJB 中,对于一般情况,处理它要容易得多。此外,根据合并方法的文档,抛出了一个 TransactionRequiredException,if invoked on a container-managed entity manager of type PersistenceContextType.TRANSACTION and there is no transaction

相关内容

  • 没有找到相关文章

最新更新