0

監査対象のエンティティAとBが2つあります。エンティティAはエンティティBのコレクションを保持しています(1対多の関係として注釈が付けられています)。Aの新しいインスタンスをデータベースに挿入すると、AとBのすべての行が同じリビジョン(たとえばリビジョン1)になります。次に、エンティティBのインスタンスにのみ影響するAの更新があります。したがって、更新後も、エンティティAはリビジョン1のままですが、Bのエンティティはリビジョン2です(監査テーブルのMODエントリを含む)。 。リビジョン3では、エンティティAが削除されます。エンティティBのコレクションには@Cascadeの注釈が付けられているため、Aに属するエンティティBも削除されます。

このシナリオで、リビジョン2の更新されたエンティティBを持つエンティティAのインスタンスを取得するEnversで監査クエリを作成するにはどうすればよいですか?エンティティAのすべてのリビジョンをクエリすると、Bのエンティティを持たないAの削除されたエンティティ(リビジョン3)を取得するか、リビジョン1のBエンティティを保持するリビジョン1のAも取得します。

それが役立つ場合は、Hibernate3.6を使用します。

4

3 に答える 3

3

私はあなたのAエンティティに相当するものに隠されたlastUpdated日付フィールドを追加することで同様の問題を解決しました。

@Entity
public class A {
    private Date lastModified;
    @OneToMany(mappedBy = "a", cascade = CascadeType.ALL )
    private List<B> blist;
    public void touch(){
        lastModified=new Date();
    }
}

次に、関連するエンティティ(Bフィールドなど)に、次のものを追加しました。

public class B {
    @ManyToOne
    private A a; 

    @PreUpdate
    public void ensureParentUpdated(){
        if(a!=null){
            a.touch();
        }
    }
}

これにより、多くのエンティティでカスタムコードが必要な場合でも、リビジョンがBに追加されるたびに、リビジョンがAに追加されます。

あなたの場合、これにより、Aの履歴に実際にBのリビジョンが含まれるようになります。このように、A、Bsグラフ全体のすべてのリビジョンを取得するために必要なクエリは1つだけです。

于 2012-06-28T12:02:20.980 に答える
2

リビジョン2でエンティティAを読み取ると、適切なデータが得られます。

現在、エンティティまたは関連するエンティティが変更されたリビジョンのリストを取得する方法はありません(あなたの場合のように、rev 2はBでのみ変更され、aでは変更されません)。

于 2012-04-12T14:00:19.363 に答える
0

Hibernateでは、lazyを指定することで子のロードを制御できます。したがって、読み取り/書き込みの両方の場合にすべての関連付けをロードするには、休止状態の構成でクラス定義に以下の行を追加する必要があります。

<cache usage="read-write"/>

CacheMode.REFRESHをマークした場合、アイテムは第2レベルのキャッシュに書き込まれます。第2レベルのキャッシュから読み取らないでください。

親の時点で子のロードに問題がない場合は、レイジーをオフにして、更新された情報を返すことができます。

于 2012-04-12T10:04:55.510 に答える