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

Ste*_*nio 10 java hibernate jpa cascade

I have a set of entities that connect to each other forming a cycle i.e., parent entity P has two one-to-many relationships with two child entities C1 and C2 and each one of these has a one-to-many relationship with another entity A. Entity A realises the association of these entities (C1,C2) and defines the relationship's attributes (it is not just a join table). All the relationships are navigable in both directions.
域对象
The following question arises from this design: What should be the cascade strategy so that entity A can be persisted/merged, given that you always invoke entity manager operations on the root entity P? Should A be cascade reachable from both paths?

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

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

eti*_*nno 3

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

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

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

当然,您也可以采取其他方式(我们都可以偷懒),但最终您可以在单个持久性流(或持久性配置)和业务流之间创建一个耦合网络。您将必须管理大量异常,并围绕您之前放置的级联策略(保存、更新、删除)执行大量配置逻辑。

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

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

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

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

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

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

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

 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.
Run Code Online (Sandbox Code Playgroud)

我希望它有帮助。