如何使用hibernate持久化HashMap

时间:2011-01-15 14:40:13

标签: java hibernate hashmap

你好我对hibernate世界很新,似乎遇到了障碍。我需要存储的对象中有一个hashmap。

private Map<String, SentimentFrequencyCounts> modelData = null;

问题是我永远不需要用这个地图搜索,排序或做任何事情我只需要用对象保存它并在加载对象时加载它,所以我希望有某种方式可以使用hibernate只是序列化它然后将它存储在CLOB或BLOB字段中,但我似乎无法找到任何方法来做到这一点。

所以我接下来试图让hibernate像这样保存它

    @OneToMany(mappedBy="ngram_data", fetch = FetchType.EAGER) 
 @MapKey(name = "attributeName") 
 public Map<String, SentimentFrequencyCounts> getModelData() {
  return modelData;
 }

但是这在运行时给了我以下异常  org.hibernate.AnnotationException: Use of @OneToMany or @ManyToMany targeting an unmapped class:

SentimentFrequencyCounts类是我试图坚持的类的内部类。所以基本上我认为我真的不明白hibernate如何为hashmap工作。真的很遗憾我不能让它将它序列化并将其集中在一个列中。

提前感谢您的帮助和时间。

2 个答案:

答案 0 :(得分:2)

@org.hibernate.annotations.Type(
        type = "org.hibernate.type.SerializableToBlobType", 
        parameters = { @Parameter( name = "classname", value = "java.util.HashMap" ) }
)
public Map<String, SentimentFrequencyCounts> getModelData() {
  return modelData;
}

或者只是在大多数情况下这会起作用(分布式缓存可能成为问题):

@org.hibernate.annotations.Type( type = "org.hibernate.type.SerializableType" )
public Map<String, SentimentFrequencyCounts> getModelData() {
  return modelData;
}

答案 1 :(得分:1)

取消现有注释并使用@Lob注释列表 - 此specifies that a persistent property or field should be persisted as a large object to a database-supported large object type

如果变量的类型是Serializable的子类型,则可以完全取消注释; JPA关于默认映射的规则声明可序列化而非原始或Embeddable的类型被序列化并存储在BLOB列中。但是,List不是Serializable,即使ArrayList是。

您可以将@Lob与@ElementCollection一起使用,但我不确定结果是什么;我不知道是否序列化了整个列表,或者创建了一个表,其中每个列表元素都是单独序列化的。无论哪种方式,你都可能不感兴趣。

多次编辑:当然,作为规范的勤奋学生,这个注释只适用于Serializable 类型的字段,而不适用于仅容纳Serializable 类。因此,为了完成这项工作,你将不得不参与恶作剧。我看看你是否能用一个以交叉类型为界的通用通配符来做一些聪明的事情,但我认为你不能。但是,你可以写一个像这样的小课:

class SerializableInstanceOf<T> implements Serializable {
    public final T instance;

    public SerializableInstanceOf(T instance) {
        Serializable s = (Serializable)instance;
        this.instance = instance;
    }
}

并将其用作列表的持有者 - 该实体具有标记为@Lob的此类型的字段,并保留对其中列表的引用。每次要使用列表时,都可以通过实例字段,可能通过实体上的getList方法。

这很难看,但它应该让你做你需要做的事。