[英]JPA Updating Bidirectional Association
让我们假设我们有以下实体:
@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);
或者正在合并拥有方? 这些合并也应该发生在Transaction或EJB中吗? 或者在具有分离实体的简单控制器方法上执行它就足够了?
问题是我应该如下所示在双方应用合并,并且我避免第二次合并级联?
您可以使用级联注释元素将操作的效果传播到关联实体。 级联功能最常用于父子关系。
如果这些关系已使用cascade
元素值cascade=MERGE
或cascade=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
是以下内容:
管理实体之间的双向关系将基于关系所属方所持有的引用而持久化。 开发人员有责任保持内存引用保持在拥有方,而保持在反方的引用在更改时保持一致。 在单向一对一和一对多关系的情况下,开发人员有责任确保遵守关系的语义。[29]
与事务需求相关 :是的,您需要合并操作一个活动事务。 摘自JPA 2规范:
当使用具有事务范围持久性上下文的实体管理器时,必须在事务环境中调用persist,merge,remove和refresh方法。 如果没有事务上下文,则抛出javax.persistence.TransactionRequiredException。
关于如何启动事务/如何设置事务:它取决于EntityManager
的类型(关于如何获取事务的方式)。 在EJB中,对于通用情况,处理它更容易。 此外,根据merge方法的文档, if invoked on a container-managed entity manager of type PersistenceContextType.TRANSACTION and there is no transaction
, if invoked on a container-managed entity manager of type PersistenceContextType.TRANSACTION and there is no transaction
抛出TransactionRequiredException。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.