如何在 Map<String, Embeddable> 上定义 MapKey 列名
Posted
技术标签:
【中文标题】如何在 Map<String, Embeddable> 上定义 MapKey 列名【英文标题】:How to define MapKey column name on Map<String, Embeddable> 【发布时间】:2017-11-02 12:52:16 【问题描述】:短版:我正在尝试创建一个:
@ElementCollection
private Map<String, Item> items;
,其中Item
是@Embeddable
,并且能够为映射的键定义在Item
表中创建的列名。休眠版本:5.0.12.Final
完整说明:
以下是重现我的问题的简化示例。
我的出发点是List
的@Embeddable
。
@Entity
public class Root
@Id
private Long code;
private String value;
@ElementCollection
private Set<Item> items;
@Embeddable
public class Item
private String keyValue;
private String otherValue;
通过这个映射,hibernate 会创建以下表格:
create table root (
code int8 not null,
value varchar(255),
primary key (code)
);
create table root_items (
root_code int8 not null,
key_value varchar(255),
other_value varchar(255)
);
alter table root_items
add constraint FK1o7au7f9ccr8144vyfgsr194v
foreign key (root_code)
references root;
到目前为止一切顺利。接下来,我尝试将List
转换为Map
并使用Item.keyValue
作为地图的键:
@Entity
public class Root
@Id
private Long code;
private String value;
@ElementCollection
private Map<String, Item> items;
@Embeddable
public class Item
private String otherValue;
它有效,但在root_items
表中,地图的键列始终称为items_key
,我无法找到如何将此名称强制为key_value
。
我尝试了以下替代方案:
@ElementCollection
@MapKeyJoinColumn(name = "keyValue")
private Map<String, Item> items;
/* @MapKey doesn't work at all.
org.hibernate.AnnotationException: Associated class not found: com.demo.Item
at org.hibernate.cfg.annotations.MapBinder.bindKeyFromAssociationTable(MapBinder.java:116)
*/
@ElementCollection
@MapKey(name = "keyValue")
private Map<String, Item> items;
@ElementCollection
@CollectionTable(joinColumns = @JoinColumn(name = "code"))
@MapKeyJoinColumn(name = "keyValue")
private Map<String, Item> items;
@ElementCollection
@JoinColumn(name = "keyValue")
private Map<String, Item> items;
@ElementCollection
@CollectionTable(joinColumns = @JoinColumn(name = "code"))
@MapKeyJoinColumn(name = "keyValue")
@Column(name = "keyValue")
private Map<String, Item> items;
但列名总是生成为items_key
:
create table root_items (
code int8 not null,
other_value varchar(255),
items_key varchar(255) not null,
primary key (code, items_key)
);
我也尝试了上述所有组合,将 keyValue
保留在 Item
中,但我只得到一个额外的列:
create table root_items (
code int8 not null,
key_value varchar(255),
other_value varchar(255),
items_key varchar(255) not null,
primary key (code, items_key)
);
我发现了类似的问题,但没有解决我的问题:
@ElementCollection with Map<Entity, Embeddable> where Entity is a field of the Embeddable
Key & value column name overrides when mapping java.util.Map with JPA annotations
是否有强制列名称为某个自定义值?
编辑 1:
我发现如果地图键是@Embeddable
,那么我可以实现它。
但我认为这不是实现这一目标的有效解决方案。我想保留地图键为String
@Entity
public class Root
@Id
private Long code;
private String value;
@ElementCollection
private Map<ItemKey, Item> items;
@Embeddable
public class ItemKey
private String keyValue;
当键是String
时,是否有强制列名称为某个自定义值?
【问题讨论】:
【参考方案1】:终于找到了。就这么简单:
@Entity
public class Root
@Id
private Long code;
private String value;
@ElementCollection
@MapKeyColumn(name = "keyValue")
private Map<String, Item> items;
我留下答案,以防它可以帮助像我一样迷茫的另一个人。:P
【讨论】:
以上是关于如何在 Map<String, Embeddable> 上定义 MapKey 列名的主要内容,如果未能解决你的问题,请参考以下文章
SWIG 如何在 Python 中包装 map<string,string>?
如何在 java springs 中注入 Map<String, List>?
如何将map<string list<>>转换成城map<string,object>
Java:如何使用 Map<String,String> 在文本中填充占位符?