Hibernate:集合的集合

20

我一直遇到这个问题:

我想让 hibernate 管理一个表示集合的集合的单个表。例如:

  • 映射的映射
  • 列表的集合
  • 映射的列表

例如,我想要能够表示这个:

class OwningClass {  
    Long entityId;  
    Map<String, List<Element>> mapOfLists;
}
class Element { String data_1; boolean data_2; }

作为一个单独的表:

OWNER (外键指向该元素的所有者) 
MAP_KEY (varchar(30) )
LIST_INDEX (int)
ELEMENT_DATA_1 (varchar(1020)
ELEMENT_DATA_2 (bit)

似乎没有可能不用自定义 hibernate 代码来实现这一点,但是我希望有人能提供一些关于自定义代码应该如何编写的指导。

  • 我应该扩展 AbstractPersistentCollection 吗?
  • CompositeUserType?

如果可以处理多个表,则有可能进行管理,但从数据库的角度来看显然不太好。


@martijn-pieters - 删除了我的回答。向他询问。 - Pat
1个回答

11

https://xebia.com/blog/mapping-multimaps-with-hibernate/ 找到了答案。

这是一篇11年前的长博客文章,关键代码如下:

public class MultiMapType implements UserCollectionType {

public boolean contains(Object collection, Object entity) {
    return ((MultiMap) collection).containsValue(entity);
}

public Iterator getElementsIterator(Object collection) {
    return ((MultiMap) collection).values().iterator();
}

public Object indexOf(Object collection, Object entity) {
    for (Iterator i = ((MultiMap) collection).entrySet().iterator(); i.hasNext();) {
        Map.Entry entry = (Map.Entry) i.next();    
        Collection value = (Collection) entry.getValue();
        if (value.contains(entity)) {
            return entry.getKey();
        }
    }
    return null;
}

public Object instantiate() {
    return new MultiHashMap();
}

public PersistentCollection instantiate(SessionImplementor session, CollectionPersister persister) throws HibernateException {
    return new PersistentMultiMap(session);
}

public PersistentCollection wrap(SessionImplementor session, Object collection) {
    return new PersistentMultiMap(session, (MultiMap) collection);
}

public Object replaceElements(Object original, Object target, CollectionPersister persister, Object owner, Map copyCache, SessionImplementor session) throws HibernateException {

    MultiMap result = (MultiMap) target;
    result.clear();

    Iterator iter = ( (java.util.Map) original ).entrySet().iterator();
    while ( iter.hasNext() ) {
        java.util.Map.Entry me = (java.util.Map.Entry) iter.next();
        Object key = persister.getIndexType().replace( me.getKey(), null, session, owner, copyCache );
        Collection collection = (Collection) me.getValue();
        for (Iterator iterator = collection.iterator(); iterator.hasNext();) {
            Object value = persister.getElementType().replace( iterator.next(), null, session, owner, copyCache );
            result.put(key, value);
        }
    }

    return result;
}

这里也有一些讨论:Hibernate中的Multimap


2
这是 Stack Overflow 上最长延迟的自问自答帖子。恭喜! - peterh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接