如何使用 hibernate 持久化 HashMap

JNR*_*JNR 6 java hibernate hashmap

您好,我对休眠世界很陌生,似乎遇到了障碍。我需要存储的对象中有一个哈希图。

private Map<String, SentimentFrequencyCounts> modelData = null;
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

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

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

Ste*_*ole 5

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

或者甚至只是这在大多数情况下都有效(分布式缓存可能是一个问题):

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


Tom*_*son 3

去掉现有的注释并使用 @Lob 对列表进行注释 - 这指定持久属性或字段应作为大对象持久保存到数据库支持的大对象类型

如果变量的类型是可序列化的子类型,则可以完全省略注释;JPA 关于默认映射的规则规定了可序列化且非原始类型或Embeddable序列化并存储在 BLOB 列中的类型。然而,List 是不可序列化的,尽管 ArrayList 是可序列化的。

您可以将 @Lob 与 @ElementCollection 一起使用,但我不确定结果是什么;我不知道这是否会序列化整个列表,或者创建一个表,其中每个列表元素都单独序列化。不管怎样,你可能都不感兴趣。

稍后编辑:当然,作为规范的勤奋学生会知道,此注释仅适用于 Serialized type的字段,而不适用于恰好保存 Serialized class的对象的字段。因此,为了使这项工作成功,你将不得不进行一些恶作剧。我研究过您是否可以使用以交集类型为界的通用通配符做一些聪明的事情,但我认为您不能。但是,您可以编写一个像这样的小类:

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

    public SerializableInstanceOf(T instance) {
        Serializable s = (Serializable)instance;
        this.instance = instance;
    }
}
Run Code Online (Sandbox Code Playgroud)

并将其用作列表的持有者 - 该实体有一个用 @Lob 标记的这种类型的字段,并在其中保留对列表的引用。每次您想要使用列表时,您都会通过实例字段,可能通过实体上的 getList 方法。

它很丑陋,但它应该让你做你需要做的事情。