我已经实现了一个包含Set的ObservableSet
类,并实现了Set接口和Observable模式,在添加或删除元素时向已注册的侦听器发送事件。我想在Hibernate映射的类中使用这个ObservableSet。 Hibernate需要Set
的getter和setter,并将它们设置为PersistentSet.
的实例。在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中监听更改。我主要担心的是,一旦我从数据库反序列化对象,我就可以听取更改。我可以编写第二个(非bean)getter,它只返回包装器ObservableSet,然后通过编码约定强制执行,我们不会改变内部集的内容,除非通过我们通过这个方法获得的包装器,但这似乎是善良的不愉快和hacky。
思想?
答案 0 :(得分:2)
您可以使用注释注释One-To-Many集合,如下所示:
@OneToMany(...)
@CollectionType(type = "some.collection.Type")
public Set<Entity> getEntities() {
return entities;
}
实现some.collection.Type,使其包装PersistentSet:
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;
}
}
列表或地图以相同的方式实施。