JPA更新双向关联
让我们假设我们有以下实体:
@Entity public class Department { @OneToMany(mappedBy="department") private List 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中吗? 或者在一个带有分离实体的简单控制器方法上做它就足够了?
问题是我应该如下所示在双方应用合并,并且我避免第二次合并级联?
您可以使用级联注释元素将操作的效果传播到关联实体。 级联function最常用于父子关系。
如果这些关系已使用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()
)。 坚持新员工并不意味着部门也是持久的(你没有级联),所以它会因为另一个原因而抛出exception(只需尝试并发布exception)。为了避免这种情况,你要么添加一个级联类型,或坚持他们两个(正如你在你的例子中所做的那样)。
关于你的问题:考虑的唯一部分是拥有方。 在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。
- 在传统世界中需要Hibernate
- HIbernate映射exception:PropertyNotFoundException:找不到setter
- Hibernate:如何覆盖映射超类的属性
- 可以在另一个查询的结果集上选择HQL吗?
- 无法通过reflection设置器设置字段值
- 这些实体的equals和hashCode(Spring MVC + Hibernate)
- JPA2 / Hibernate – 停止延迟加载?
- java.lang.OutOfMemoryError:PermGen space Exception
- Spring JPA(Hibernate)没有类型的限定bean:javax.persistence.EntityManagerFactory