10

相互に接続してサイクルを形成する一連のエンティティがあります。つまり、親エンティティ P には、2 つの子エンティティ C1 および C2 との 2 つの 1 対多の関係があり、これらのそれぞれは、別のエンティティとの 1 対多の関係にあります。 A. エンティティ A は、これらのエンティティ (C1、C2) の関連付けを実現し、関係の属性を定義します (単なる結合テーブルではありません)。すべての関係は双方向にナビゲート可能です。
ドメイン オブジェクト
この設計から、次の疑問が生じます。ルート エンティティ P で常にエンティティ マネージャ操作を呼び出す場合、エンティティ A を永続化/マージできるようにするためのカスケード戦略はどうあるべきか? A は、両方のパスから到達可能なカスケードにする必要がありますか?

考慮事項:アプリケーションが 1 つのカスケード パスのみを提供することを選択した場合、TransientObjectException をスローするシナリオが発生する可能性があるようです。両方のパスを提供する場合、これらのパスは完全なサイクルを作成する必要があります。たとえば、C1 は A を介して保存しようとする可能性があります。

バージョン: JPA 2.0、Hibernate コア 4.1.7、hibernate-jpa-2.0-api 1.0.1

4

2 に答える 2

3

私の答えが少し長い場合は申し訳ありませんが、私はあなたに私の2セントを与えることができます。

この種のカスケード競合がある場合は、カスケードアプローチまたはドメインモデルが十分に定義されていないことが原因である可能性があります。カスケード戦略を全体的なグラフ、または無関係な要素のセットに一般化するように注意します。

私のアドバイスは、カスケード戦略は、Javaの世界のクラスとその(プライベート)内部クラスのように、強く結び付けられた同じタイプのデータセットでのみ使用する必要があるということです。マザークラスとその子クラスの関係も排他的である必要があります(UMLでは非共有アソシエーションと呼ばれます)。

もちろん、他の方法で行うこともできますが(私たち全員が怠惰になる可能性があります)、最後に、単一の永続フロー(または永続構成)とビジネスフローの間の結合のウェブを作成できます。多くの例外を管理し、以前に設定したカスケード戦略(保存、更新、削除)の周りで多くの構成ロジックを実行する必要があります。

極端なアプローチは、1つの大きなルートオブジェクトのみを保存したい場合があるということです。なぜだめですか?残りは「カスケードで持続する必要があります」。しかし実際には、これによりシステムの保守性が大幅に制限される可能性があります。さらに、グラフをロード、保存、およびマージするときに、メモリ内の大きなグラフの状態を管理する必要がある場合があります。

Webアプリケーション、または任意のクライアントサーバーアプリケーションを実行する場合、Webワークフローは、ルート要素からすべてを保存しなくても、要求ごとに限られたオブジェクトのセットを保存できる必要があります。私はあなたの質問に直接答えていないことを知っています。では、例に戻りましょう。

Pが銀行で、C1とC2が2つのクライアントであり、Aが製品であるとします。

簡単な答えは2つあります。1)各レイヤーはカスケードせずに個別に保存できます。ただし、必要に応じて、同じトランザクション内で、同じDAO内で実行することも、実行しないこともできます。

2)PとCはカスケード接続できます。ただし、Aは別のワークフローで保存する必要があります。

これは、PeterCoadが「ドメイン駆動分析」について話している章を思い出させます。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.

お役に立てば幸いです。

于 2012-11-29T18:56:49.150 に答える
3

一般に、親から子(または所有者から所有) の方向にのみ、密接な関連付けでのみカスケードすることをお勧めします。あなたの場合、おそらくP->C1と になりP->C2ます。Aには明らかな親が 1 つもないため、個別に保存する必要があります。これは、DAO で @etienno がP(およびC1, C2) と一緒に単一のトランザクションで言及されているように実行できます。私はあなたのドメインモデルを知りませんAが、概念レベルでは別のエンティティである可能性があります。その場合、別の保存がさらに正当化されます。

密接に関連していない多くのオブジェクトにカスケードすると、長期的にはグラフ全体が大きくなり、管理できなくなる可能性があります。

このような状況では、「Hibernate なしでどのように行うか」という質問をするのは常に良いことです。あなたの場合、おそらく最初に保存Pし、次にC1C2そしてA. AFAIK JPA/Hibernate は、そのような順序を強制する明示的な方法を提供していないため、いくつかのことを手動で行う必要があります。

于 2012-12-04T12:01:57.047 に答える