繁体   English   中英

如何映射地图 <String, List<String> &gt;在休眠状态

[英]How to map Map<String, List<String>> in hibernate

我正在使用当前的Spring Data JPA,我想映射一个属性

@Entity
public class Outer {
    ...
    Map<String, List<String>> typesToCategories;
}

假设我有一个table outerouter_type_category 第一个是微不足道的:只有列outer_id与它相关

CREATE TABLE outer_types_categories ( 
    id        uuid                        NOT NULL,
    outer_id  uuid                        NOT NULL,
    type      character varying(128)      NOT NULL,
    category  character varying(128)      NOT NULL,
    ...
 )

我应该使用哪些注释(如果可能的话)将此表映射到地图?

我试过用这个

    @ElementCollection
    @CollectionTable(name = "outer_type_category", joinColumns = [JoinColumn(name = "outer_id")])
    @MapKeyColumn(name = "type")
    @Column(name = "category")
    Map<String, List<String>> typesToCategories;

但最后我看到一个例外:

Caused by: org.hibernate.MappingException: Could not determine type for: java.util.List, at table: outer_type_category, for columns: [org.hibernate.mapping.Column(category)]

我忘了什么吗?

JPA指定了

实体或可嵌入类的持久字段或属性可以对应于基本类型或可嵌入类的集合(“元素集合”)。

(JPA 2.2规范,第2.6节;增加了重点)

java.util.List既不是基本类型也不是可嵌入类,因此它不属于元素集合的允许元素类型。 此外,JPA继续说

包含在元素集合中的可嵌入类[...]不得包含元素集合

,所以即使用可嵌入类替换List也没有为你提供一个合适的机制来映射你所描述的结构。 如果您根本不愿意或根本无法更改数据库结构,那么我认为您不能以与您描述的方式类似的方式映射您的表。

如果你至少可以向数据库添加一个新表,那么你可以引入一个表示地图中一个条目的新实体,比如说OuterType ,它有一个映射到你的outer_types_categories表的元素集合。 它可能需要具有对应于(outer_id, type)的复合ID。 即使这样,数据库端也需要设置为自动将值分配给集合表的id列(除非您可以删除该列,实际上这对于您的明显目的似乎没有用),因为成员元素集合不是实体,因此JPA不会将ID归于它们。 此外,(在JPA方面)有一个列既是复合主键的一部分又是相关实体的外键,这是必要的。

如果你有更多的自由来修改数据库结构,那么我会建立上述OuterType与标准,代理ID以及与双向one-to-一个关系的实体Outer ,在代表Outer侧的地图。 使用默认映射策略设置包含OuterType中的类别字符串的元素集合,该策略将使用OuterType的(代理)ID以及集合表中的“type”和“outer_id”。

暂无
暂无

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

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