3

日付フィールドが他のエンティティの状態に依存している場合、日付フィールドを維持し、できればその値を永続化する必要があるという問題に遭遇しました。JPA2 + Hibernate + Springでこの問題に対処する正しい方法は何ですか?

Parent基本的に、3 つのエンティティがあり、それらを 、Child、および と呼びましょうConf。はdependentDate、他のエンティティの状態に依存する複雑なビジネス ルールによって計算されます。具体的には、土日祝日を除くすべての日をスキップしてParent#dateマイナスにする必要があります (永続データ)。Conf#delay

問題は、Parent#dateが変更されるたびに、すべての子のdependentDateを再計算する必要があることです。Childこれは、オブジェクトconfが変更されるたびに発生するはずです。現在、オブジェクトの関係に基づいて新しい日付を計算するサービス メソッドがありChildます (これを と呼びましょうcalculateDate())。

フィールドの値をどこで計算するかという問題に直面しています。私は3つの可能な解決策を思いつきました。他のエンティティの状態に依存するエンティティのフィールドを更新する好ましい方法は、次のうちどれですか?

  1. JPAEntityListener
    • EntityListeners は他のエンティティにアクセスしてはならないため、これは JPA2 仕様では推奨されていません。
    • フィールドは常に正しいでしょう
  2. 更新する Spring AOP アスペクト
    • ロジックは他のクラスに隠され、簡単には見えません
    • ポイントカットがすべての永続化/更新イベントをキャッチしないというリスク
  3. すべての開発者が自分のために
    • 親クラスまたは子クラスのインスタンスを更新するときは常に、開発者はサービスのcalculateDate()メソッドを呼び出すことを忘れないでください。
    • これはdaoまたはサービスレイヤーにある必要がありますか?
    • 開発者が呼び出しを追加するのを忘れて、誤った状態になるリスク

次の例は、アノテーション構成を省略したエンティティ関係を示しています。

エンティティ

public class Parent {
     LocalDate date;
     Set<Child> children;     // one-to-many
}

public class Conf {
     int delay;
}

public class Child {
     LocalDate dependentDate;
     Conf conf;               // many-to-one
     Parent parent;           // many-to-one
}
4

2 に答える 2

2

複数のエンティティの状態に依存する複雑なビジネス ルールは、サービス層に属します。親の日付と子の conf が変更されるアプリケーション内の場所はそれほど多くないはずです。そのため、新しい日付の計算を行う必要がある場所がそれほど多くあるべきではありません。

これが行われる場所が非常に多い場合は、ChildDateUpdater インスタンス (ChildDateUpdater はインターフェイス) を親日付のセッターと子 conf のセッターに渡すことによって、日付を再計算する必要があることを明確にすることができます。これにより、これら 2 つのフィールドが変更されるたびに何かを行う必要があることが明らかになります。

親で:

public void setDate(Date date, ChildDateUpdater childDateUpdater) {
    this.date = date;
    for (Child child : children) {
        childDateUpdater.updateChildDate(child);
    }
}

子の場合:

public void setConf(Conf conf, ChildDateUpdater childDateUpdater) {
    this.conf = conf;
    childDateUpdater.updateChildDate(this);
}
于 2012-11-23T09:15:46.453 に答える
0

データ アクセスを DAO にカプセル化します。を保存するときParentは、その値に変更があったかどうかを確認し、変更があった場合はそれに応じて子を更新します。

のトリガー オプションrealsimも実行可能です (基本的には、別のレベルで実装された同じアイデアです) が、移植性が失われます (また、既に読み込まれた Children のインスタンスが更新されないという問題もあります)。

于 2012-11-23T09:14:02.673 に答える