java - JPA+Hibernate - 实体关系中的循环 - 级联策略

标签 java hibernate jpa cascade

我有一组实体,它们相互连接形成一个循环,即父实体 P 与两个子实体 C1 和 C2 有两个一对多关系,每个子实体都有一对多关系与另一个实体A。实体A实现了这些实体(C1,C2)的关联并定义了关系的属性(它不仅仅是一个连接表)。所有关系都可以在两个方向上导航。
domain objects
这个设计产生了以下问题:假设您总是在根实体 P 上调用实体管理器操作,那么级联策略应该是什么,以便实体 A 可以持久化/合并? A 是否应该从两条路径级联可达?

注意事项:似乎如果应用程序选择仅提供一个级联路径,则可能会出现抛出 TransientObjectException 的情况。如果它提供两条路径,那么这些路径必须形成完整的循环,例如可以尝试通过 A 保存 C1。

版本:JPA 2.0、Hibernate 核心 4.1.7、hibernate-jpa-2.0-api 1.0.1

最佳答案

我可以给你我的 2 美分,如果我的回答有点长,抱歉。

如果您遇到此类级联冲突,可能是因为您的级联方法或领域模型定义不当。我会小心地将级联策略推广到整体图或一组不相关的元素。

我的建议是,级联策略应该只应用于强绑定(bind)在一起且类型相同的数据集,例如 Java 世界中的类及其(私有(private))内部类。母类与其子类之间的关系也应该是排他的(在 UML 中称为非共享关联)。

当然你可以做其他事情(我们都可以懒惰),但最后你可能会在你的单一持久性流(或持久性配置)和你的业务流之间创建一个耦合网络。您将不得不管理大量异常,并围绕您之前放置的级联策略(保存、更新、删除)执行大量配置逻辑。

极端的方法是有些人可能只想保存一个大的根对象。为什么不?其余的“应该坚持级联”。但实际上,这可能会严重限制系统的可维护性。此外,在加载、保存和合并大图时,您可能必须在内存中管理大图的状态。

如果你做一个网络应用程序,或者任何客户端-服务器应用程序,你的网络工作流应该能够在每次请求时保存一组有限的对象,而不必保 stub 元素中的所有内容。我知道我不是直接回答你的问题。那么让我们回到您的示例:

假设 P 是一家银行,C1 和 C2 是两个客户,A 是一个产品。

我有两个简单的答案: 1)每一层都可以单独保存,没有任何级联。但它可以在同一个事务中完成,如果你愿意,也可以在同一个 DAO 中完成。

2) P和C“可以”级联。但是A必须保存在不同的工作流中。

这让我想起了 Peter Coad 的一章,他谈到了“领域驱动分析”:http://www.petercoad.com/download/bookpdfs/jmcuch01.pdf

本章解释了如何在不同的原型(prototype)中分离图中的不同对象。事务数据和描述或“事物”之间的持久性工作流不应该相同。这有助于制定更好的级联策略:

 The four archetypes of Peter Coad are:
 - Is it a moment or interval? 
 - Is it a role played? 
 - Is it a catalog-entry-like description? 
 - Otherwise, it's a party, place, or thing.

希望对你有帮助。

关于java - JPA+Hibernate - 实体关系中的循环 - 级联策略,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13622070/

相关文章:

java - 需要 Java 版本的 Maven 依赖项?

java - char-in 字符串出现一个错误

hibernate - 实现接口(interface)的枚举类型的映射集合

hibernate - 在 JPA 中为什么以及如何使用可插入和可更新参数?

java - hibernate @Id @GenerateValue 具有非自动增量,并且我没有序列

java - Mockito - 如何使用列表匹配器限制列表类型?

java - Hibernate 聚合 + Spring MVC

java - 如何为 Spring Boot 应用程序设置 org.hibernate.org.hibernate.FlushMode?

java - 金融应用中的事务隔离级别

java - Hibernate DTD 未从类路径加载,jar 在那里,仍然出现 FileNotFoundException