如何在JPA 2.1中映射值集合非唯一的Map<String, Entity>?
JPA 2.1映射非唯一值的单向Map<String, Entity>
我懂你现在的困扰——网上搜出来的Map映射方案几乎全是值唯一的场景,但你需要的是同一个Entity实例能对应多个不同的key。别慌,JPA 2.1完全能搞定这个需求,核心是用@ElementCollection配合中间表实现,而非常规的@OneToMany/@ManyToMany。
先看你的基础实体类,Entity2保持原样就行:
@Entity public class Entity2 implements Serializable { private static final long serialVersionUID = 1L; @Id private Long id; // 构造方法、getter和setter按需实现 }
重点是修改Entity1的Map映射,具体配置如下:
@Entity public class Entity1 implements Serializable { private static final long serialVersionUID = 1L; @Id private Long id; // 核心的非唯一值Map映射 @ElementCollection @CollectionTable( name = "entity1_entity2_assoc", // 自定义中间表名称 joinColumns = @JoinColumn(name = "entity1_id") // 关联Entity1的外键列 ) @MapKeyColumn(name = "map_key") // 存储Map中String类型key的列 @ManyToOne @JoinColumn(name = "entity2_id") // 关联Entity2的外键列 private Map<String, Entity2> entityMap; // 构造方法、getter和setter按需实现 }
配置逻辑拆解
@ElementCollection:我们要存储的是一组“键-实体引用”的条目,而非实体间的直接唯一关联,这个注解刚好适配这种值集合场景。@CollectionTable:指定存储键值对的中间表,同时定义和Entity1的关联外键。@MapKeyColumn:明确中间表中存放Map的key的列名,确保同一个Entity1下的key是唯一的(毕竟Map本身的key不能重复)。@ManyToOne+@JoinColumn:这是实现“值非唯一”的关键——它允许中间表中多个条目指向同一个Entity2实例,也就是不同的key可以对应同一个Entity2。
中间表结构说明
生成的中间表entity1_entity2_assoc会包含三个字段:
entity1_id:外键,关联Entity1的idmap_key:存储Map的String keyentity2_id:外键,关联Entity2的id
这个表的主键通常是entity1_id + map_key的组合(保证同一个Entity1下key不重复),但entity2_id可以重复,完美满足你的需求——比如可以有这样的记录:
| entity1_id | map_key | entity2_id |
|---|---|---|
| 1 | keyA | 2 |
| 1 | keyB | 2 |
避坑提示
别尝试用@OneToMany配合@MapKeyJoinColumn,这种方式会强制每个Entity2只能被一个key关联,完全不符合你“值非唯一”的要求。@ElementCollection+@ManyToOne的组合才是正确的打开方式。
内容的提问来源于stack exchange,提问作者Kalle Richter
相关产品推荐
相关产品推荐

