2

ObservableSetSet をラップし、Set インターフェイスと Observable パターンを実装するクラスを実装し、要素が追加または削除されたときに登録済みのリスナーにイベントを発生させます。Hibernate がマップするクラスでこの ObservableSet を使用したいと思います。Hibernate は の getter と setter を必要Setとし、それらを のインスタンスに設定しますPersistentSet.As in this question from 2010、最初に Getter と Setter にロジックを追加して、渡された Set を ObservableSet でラップしようとしましたが、これにより例外が発生します。Exception in thread "main" org.hibernate.HibernateException: A collection with cascade="all-delete-orphan" was no longer referenced by the owning entity instance: ...

Hibernate 内からの変更をリッスンする必要はありません。私の主な関心事は、データベースからオブジェクトを逆シリアル化すると、変更をリッスンできることです。ラッパー ObservableSet を返すだけの 2 番目の (Bean ではない) ゲッターを作成し、このメソッドを介して取得するラッパーを除いて内部セットの内容を変更しないというコーディング規則を強制することもできますが、それは親切に思えます不快でハッキーの。

考え?

4

1 に答える 1

2

次のように、1 対多のコレクションに注釈を付けることができます。

@OneToMany(...)
@CollectionType(type = "some.collection.Type")
public Set<Entity> getEntities() {
    return entities;
}

そして、PersistentSet をラップするように some.collection.Type を実装します。

public class TestCollectionType implements UserCollectionType {
    @Override
    public PersistentCollection instantiate(SessionImplementor session, CollectionPersister persister)
                    throws HibernateException {
            return new Wrapper(new PersistentSet(session));
    }
    @Override
    public Object instantiate(int anticipatedSize) {
            return new Wrapper(new HashSet<>());
    }

    @Override
    public PersistentCollection wrap(SessionImplementor session, Object collection) {
            return new Wrapper(new PersistentSet(session, (Set<?>)collection));
    }

    @Override
    public Iterator getElementsIterator(Object collection) {
            return ((Set<?>)collection).iterator();
    }

    @Override
    public boolean contains(Object collection, Object entity) {
            return ((Set<?>)collection).contains(entity);
    }

    @Override
    public Object indexOf(Object collection, Object entity) {
            throw new UnsupportedOperationException();
    }

    @Override
    public Object replaceElements(Object original, Object target, CollectionPersister persister, Object owner,
                    Map copyCache, SessionImplementor session) throws HibernateException {
            ((Set<?>)target).clear();
            ((Set<?>)target).addAll((Set)original);
            return target;
    }
}

List または Map も同じ方法で実装されます。

于 2014-06-03T13:20:04.320 に答える