简体   繁体   English

如何使用hibernate持久化HashMap

[英]How to persist a HashMap with hibernate

Hello I am very new to the hibernate world and seem to have hit a roadblock. 你好,我对hibernate世界很新,似乎遇到了障碍。 The object I need to store has a hashmap in it. 我需要存储的对象中有一个hashmap。

private Map<String, SentimentFrequencyCounts> modelData = null;

The thing is I will never need to search, sort or do any thing with this map I just need to save it with the object and load it when the object is loaded, so I was hoping there was some way that hibernate could just serializes it and then store it in a CLOB or BLOB field but I can not seem to find any way to do that. 事情是我永远不需要用这个地图搜索,排序或做任何事情我只需要用对象保存它并在加载对象时加载它,所以我希望有一些方法可以让hibernate序列化它然后将它存储在CLOB或BLOB字段中,但我似乎无法找到任何方法。

So I next tried to have hibernate save this like so 所以我接下来试图让hibernate这样保存

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

But this gives me the following exception at runtime org.hibernate.AnnotationException: Use of @OneToMany or @ManyToMany targeting an unmapped class: 但是这在运行时给出了以下异常org.hibernate.AnnotationException: Use of @OneToMany or @ManyToMany targeting an unmapped class:

The SentimentFrequencyCounts class is an inner class of the one I am trying to persist. SentimentFrequencyCounts类是我试图坚持的类的内部类。 So basically I think I really am not understanding how hibernate works for hashmap. 所以基本上我认为我真的不明白hibernate如何为hashmap工作。 Really a shame I can not just get it to serialize this and lump it up in a single column. 真的很遗憾我不能让它序列化这个并将它集中在一个列中。

Thanks in advance for your help and time. 在此先感谢您的帮助和时间。

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

Or even just this will work in most cases (distributed caching might be a problem): 或者只是在大多数情况下这会起作用(分布式缓存可能是个问题):

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

Take off your existing annotations and annotate the list with @Lob - this specifies that a persistent property or field should be persisted as a large object to a database-supported large object type . 取消现有注释并使用@Lob注释列表 - 这指定持久属性或字段应作为大对象持久保存到数据库支持的大对象类型

If the type of the variable was a subtype of Serializable, you could just leave off the annotations altogether; 如果变量的类型是Serializable的子类型,则可以完全省略注释; JPA's rules on default mappings state that types which are Serializable and not primitive or Embeddable are serialized and stored in BLOB columns. JPA关于默认映射的规则声明可序列化且非原始或Embeddable类型被序列化并存储在BLOB列中。 However, List is not Serializable, even though ArrayList is. 但是,List不是Serializable,即使ArrayList是。

You can use @Lob with @ElementCollection, but i'm not sure what the result is; 您可以将@Lob与@ElementCollection一起使用,但我不确定结果是什么; i don't know if that serializes the whole list, or creates a table in which each list element is serialized separately. 我不知道是否序列化了整个列表,或者创建了一个表,其中每个列表元素都是单独序列化的。 It probably isn't of interest to you either way. 无论哪种方式,你都可能不感兴趣。

MUCH LATER EDIT: Of course, as a diligent student of the spec will know, this annotation only works for fields of Serializable type , not fields which merely happen to hold objects of a Serializable class . 多次编辑:当然,作为规范的勤奋学生,这个注释只适用于Serializable 类型的字段,而不仅仅适用于容纳Serializable 对象的字段。 Consequently, to make this work, you will have to engage in shenanigans. 因此,为了完成这项工作,你将不得不参与恶作剧。 I had a look at whether you could do something clever with a generic wildcard bounded with an intersection type, but i don't think you can. 我看看你是否能用一个以交叉类型为界的通用通配符来做一些聪明的事情,但我认为你不能。 You can, however, write a little class like this: 但是,您可以像这样编写一个小类:

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

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

And use that as a holder for the list - the entity has a field of this type marked with @Lob, and keeps a reference to the list in it. 并使用它作为列表的持有者 - 实体具有标记为@Lob的此类型的字段,并保留对其中列表的引用。 Every time you want to work with the list, you go via the instance field, probably via a getList method on the entity. 每次要使用列表时,都可以通过实例字段,可能通过实体上的getList方法。

It's ugly, but it should let you do what you need to do. 这很难看,但它应该让你做你需要做的事情。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM