4

私はこのようなエンティティを持っているとしましょう

@Entity
Class A{
//fields

@Onetomany
Set<B> b; // 
}

ここで、コレクションに新しいエントリがある場合に、LinkedHashMapにあるremoveEldestEntryのように、最も古いエントリが削除されるように、コレクション内の'Bの数を制限するにはどうすればよいですか。

MySQL5.5DBをHibernateで使用しています。前もって感謝します。

編集

私の目標は、どの時点でもそのテーブルにN個を超えるエントリを含めないことです。私が持っている解決策の1つは、Setを使用してジョブをスケジュールし、古いエントリを削除することです。しかし、私はそれが汚れていると思います。よりクリーンなソリューションを探しています。

4

3 に答える 3

2

ApacheCommonsCollectionによって提供されるAPIが1つあります。ここでは、同じ問題を参照するためにクラスCircularFifoBufferを使用できます。以下に示す例が必要な場合は、それを達成できます。

Buffer buf = new CircularFifoBuffer(4);
buf.add("A");
buf.add("B");
buf.add("C");
buf.add("D"); //ABCD
buf.add("E"); //BCDE
于 2012-12-23T06:46:03.763 に答える
2

このコードを使用して、このルールを手動で適用します。主なアイデアは、クライアントがパブリックメソッド(つまりaddB())によってのみコンテンツを変更できるように、コレクションBを適切にカプセル化する必要があるということです。addB()コレクションB内のエントリ数が値を超えないようにするには、このメソッド()内でこのルールを確認するだけです。

A:

@Entity
public class A {


    public static int MAX_NUM_B = 4;

    @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
    private Set<B> b= new LinkedHashSet<B>();

    public void addB(B b) {
        if (this.b.size() == MAX_NUM_B) {
            Iterator<B> it = this.b.iterator();
            it.next();
            it.remove();
        }
        this.b.add(b);
    }

    public Set<B> getB() {
        return Collections.unmodifiableSet(this.b);
    }
}

B:

@Entity 
public class B{

    @ManyToOne
    private A a;
}

主なポイント:

  • Aは関係の所有者である必要があります。
  • Aでは、クライアントがに実装されているチェックロジックをバイパスしてその内容を自由に変更できるため、単にBを返さないでくださいaddB(B b) 。代わりに、Bの変更不可能なビューを返します。
  • @OneToManyで、orphanRemovaltrueに設定すると、対応するインスタンスがBコレクションから削除された後にBのDBレコードを削除するようにJPAに指示します。
于 2012-12-23T07:23:30.757 に答える
1

手動でやらなければならないと思います。

頭に浮かぶ解決策の1つは、エンティティ@PrePersistでイベントリスナーを使用することです。@PreUpdateA

上記のアノテーションが付けられたメソッド内で、サイズがSet<B>最大制限を超えているかどうかを確認し、最も古いBエントリを削除します(Bのcreated_timeタイムスタンププロパティによって追跡される場合があります)

于 2012-12-23T06:38:14.697 に答える