开发者

How to persist a HashMap with hibernate

开发者 https://www.devze.com 2023-02-05 01:32 出处:网络
Hello I am very new to the hibernate world and seem to have hit a roadblock. The object I need to store has a hashmap in it.

Hello I am very new to the hibernate world and seem to have hit a roadblock. The object I need to store has a hashmap in it.

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.

So I next tried to have hibernate save this like so

    @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:

The SentimentFrequencyCounts class is an inner class of the one I am trying to persist. So basically I think I really am not understanding how hibernate works for 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.

If the type of the variable was a subtype of Serializable, you could just leave off the annotations altogether; JPA's rules on default mappings state that types which are Serializable and not primitive or Embeddable are serialized and stored in BLOB columns. However, List is not Serializable, even though ArrayList is.

You can use @Lob with @ElementCollection, but i'm not sure what the result is; 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. 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. Every time you want to work with the list, you go via the instance field, probably via a getList method on the entity.

It's ugly, but it should let you do what you need to do.

0

精彩评论

暂无评论...
验证码 换一张
取 消