[英]How to persist a custom map with Hibernate/JPA?
I am trying to persist a sub-classed HashMap
in a database using Hibernate and JPA annotations. 我试图使用Hibernate和JPA批注将子类
HashMap
保留在数据库中。
import javax.persistence.CollectionTable;
import javax.persistence.Column;
import javax.persistence.ElementCollection;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.MapKeyColumn;
import javax.persistence.Table;
@Entity
@Table(name = "module")
public class Module {
@Id
@GeneratedValue
@Column(name = "id")
private int id;
@Column(name = "name")
private String name;
@Column(name = "description")
private String description;
@Column(name = "version")
private String version;
@ElementCollection(fetch = FetchType.EAGER)
@CollectionTable(name = "module_parameter")
@MapKeyColumn(name = "key")
@Column(name = "value")
private Parameters params = new Parameters();
// Getters & setters
}
This gives me the following exception when trying to store parameters: 尝试存储参数时,这给了我以下异常:
org.hibernate.AnnotationException: Illegal attempt to map a non collection as a @OneToMany, @ManyToMany or @CollectionOfElements: Module.params
When I change the declaration to 当我将声明更改为
private Map<String, String> params = new Parameters();
public Parameters getParams() {
return (Parameters) params;
}
I get the following output: 我得到以下输出:
Hibernate: select module0_.id as id1_0_, module0_.description as descript2_0_, module0_.name as name3_0_, module0_.version as version4_0_ from module module0_
Hibernate: select params0_.Module_id as Module_i1_0_0_, params0_.value as value2_1_0_, params0_.key as key3_0_ from module_parameter params0_ where params0_.Module_id=?
Exception in thread "main" java.lang.ClassCastException: org.hibernate.collection.internal.PersistentMap cannot be cast to Parameters
If I change it to 如果我将其更改为
private Map<String, String> params = new HashMap<>();
everything works fine. 一切正常。
So how can I tell Hibernate about Parameters
being a collection? 那么我如何告诉Hibernate
Parameters
是一个集合呢?
You have to create a class that implements UserCollectionType interface and then provide this class to hibernate to tell that you want to use the custom collection. 您必须创建一个实现UserCollectionType接口的类,然后提供此类以使其休眠以告知您要使用自定义集合。
See these links to understand how you can create custom collections: 请参阅以下链接以了解如何创建自定义集合:
This is untested . 这是未经测试的 。 Perhaps you can try and see if this works: Why not just return a
Map<String, String>
? 也许您可以尝试看看是否可行:为什么不只返回
Map<String, String>
?
JPA works using common collection interfaces: List
, Set
, Map
. JPA使用常见的收集接口工作:
List
, Set
, Map
。 Thus, if Parameters
IS-A Map
, you can return it as a Map
. 因此,如果
Parameters
IS-A Map
,则可以将其作为Map
返回。
Change: 更改:
public Parameters getParams() {
return (Parameters) params;
}
To: 至:
public Map<String, String> getParams() {
return params;
}
Also, because Hibernate has classes that allows lazy loading, ie, PersistentList
, PersistentSet
, PersistentMap
, etc., you can use composition to return a Parameters
of what is returned by Hibernate. 另外,由于Hibernate具有允许延迟加载的类,即
PersistentList
, PersistentSet
, PersistentMap
等,因此您可以使用composition返回由Hibernate返回的Parameters
。
So, you can essentially customize your method to return the values from the returned Hibernate collection. 因此,您实质上可以自定义方法,以从返回的Hibernate集合返回值。
Something of this effect: 这种效果:
public Map<String, String> getParams() {
return new Parameters(params); //params is injected with Hibernate's PersistentMap.
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.