Jam*_*ton 8 java dictionary annotations hibernate jpa
我正在研究使用Hibernate 4.1.9和JPA注释注释地图的不同方法.
如果我想存储一个Map,其中键是实体值的属性,则标记看起来像这样
@OneToMany(mappedBy = "deptById", targetEntity = com.demo.impls.Employee.class)
@MapKey(name = "entityId")
private Map<Long, Employee> employeesById;
Run Code Online (Sandbox Code Playgroud)
请注意,上面的标记不会创建连接表,但是Map会在运行时通过查询返回,因此Map是动态的,您不必在Java中将元素添加到地图中,以便查询返回它们.
现在我希望Map的内容能够反映应用程序添加到Map中的内容,而不是执行动态查询.
我想存储4种地图
private Map<String, String> map0;
private Map<String, Entity> map1;
private Map<Entity, String> map2;
private Map<Entity, Entity> map3;
Run Code Online (Sandbox Code Playgroud)
在这些情况下,密钥和价值之间没有任何关系,也没有与持有实体有任何关系.我必须能够指定连接表的名称以及键和值的列名.
我尝试了以下内容
@Entity
public class Department {
@ElementCollection
@CollectionTable(name = "TEST_MAP0")
@Column(name="value")
@MapKeyColumn(name="Key")
private Map<String, String> map0;
@ElementCollection(targetClass = com.demo.bb.impls.Employee.class)
@CollectionTable(name = "TEST_MAP1")
@Column(name="value")
@MapKeyColumn(name="Key")
private Map<String, Employee> map1;
@ElementCollection
@MapKeyClass(value = com.demo.bb.impls.Employee.class)
@CollectionTable(name = "TEST_MAP2")
@Column(name="value")
@MapKeyColumn(name="Key")
private Map<Employee, String> map2;
@ElementCollection(targetClass = com.demo.bb.impls.ParkingSpace.class)
@MapKeyClass(value = com.demo.bb.impls.Employee.class)
@CollectionTable(name = "TEST_MAP3")
@Column(name="value")
@MapKeyColumn(name="Key")
private Map<Employee, ParkingSpace> map3;
Run Code Online (Sandbox Code Playgroud)
案例0地图工作正常,生成的连接表包含DEPARTMENT,VALUE,KEY列
其他三种情况可以在表中存储数据,在Java中使用相关键/值查询表并获取预期结果 - 即它确实使用@ElementCollection处理存储实体
但是当键或值是实体时,将忽略使用@Column(name ="value")和@MapKeyColumn(name ="key")的列名覆盖.
我尝试使用@ManyToMany注释如下
@ManyToMany(targetEntity = com.demo.bb.impls.Employee.class)
@JoinTable(name = "TEST_MAP1_B")
@Column(name="value")
@MapKeyColumn(name="Key")
private Map<String, Employee> map1_B;
@ManyToMany(targetEntity = com.demo.bb.impls.ParkingSpace.class)
@MapKeyClass(value = com.demo.bb.impls.Employee.class)
@JoinTable(name = "TEST_MAP3_B")
@Column(name="value")
@MapKeyColumn(name="Key")
private Map<Employee, ParkingSpace> map3_B;
Run Code Online (Sandbox Code Playgroud)
但同样会忽略键和值列名称覆盖.有没有人知道强制执行这些列名覆盖的方法.
提前致谢...
更新....在查看@wypieprz的响应后,我想我知道正确的注释,允许您在使用实体值的基本键入Map时为值和键指定列名.
通过使用以下
@ManyToMany(targetEntity = com.demo.bb.impls.Employee.class)
@JoinTable(name = "TEST_MAP1", inverseJoinColumns=@JoinColumn(name="VALUE"))
@MapKeyColumn(name="KEY")
private Map<String, Employee> map1;
Run Code Online (Sandbox Code Playgroud)
使用inverseJoinColumn我可以指定值列名.
但是如果密钥是实体,我还没有找到指定密钥列名称的方法.正如文档所说@MapKeyColumn"指定地图的键列的映射,其映射键是基本类型"
当密钥是实体并且值是基本值时,我也不确定要使用的注释.使用ManyToMany只是不起作用我认为我可能必须使用ElementCollection但我再也找不到指定键列名称的方法.
更新2 ...感谢Peter Halicky的解决方案.
总而言之,要为每个案例命名所有3列,您需要执行类似的操作.
@ElementCollection
@CollectionTable(name = "TEST_MAP0", joinColumns = @JoinColumn(name = "DEPARTMENT"))
@Column(name = "value")
@MapKeyColumn(name = "key")
private Map<String, String> map0;
@ManyToMany(targetEntity = com.hibernate.elephants.Employee.class)
@JoinTable(name = "TEST_MAP1", joinColumns = @JoinColumn(name = "DEPARTMENT"), inverseJoinColumns = @JoinColumn(name = "value"))
@MapKeyColumn(name = "key")
private Map<String, Employee> map1;
@ElementCollection
@CollectionTable(name = "TEST_MAP2", joinColumns = @JoinColumn(name = "DEPARTMENT"))
@MapKeyClass(value = com.hibernate.elephants.Employee.class)
@MapKeyJoinColumn(name = "key")
@Column(name = "value")
private Map<Employee, String> map2;
@ManyToMany(targetEntity = com.hibernate.elephants.ParkingSpace.class)
@JoinTable(name = "TEST_MAP3", joinColumns = @JoinColumn(name = "DEPARTMENT"), inverseJoinColumns = @JoinColumn(name = "value"))
@MapKeyClass(value = com.hibernate.elephants.Employee.class)
@MapKeyJoinColumn(name="key")
private Map<Employee, com.hibernate.elephants.ParkingSpace> map3;
Run Code Online (Sandbox Code Playgroud)
注意两种情况被指定为ElementCollection,但是值为另一种实体的两种情况需要使用ManyToMany.
小智 6
我正在使用实体作为地图的关键,如下所示.使用@MapKeyJoinColumn注释我可以指定作为地图关键字的列的名称.这在Hibernate上对我有用,不知道其他JPA实现会做什么,但它肯定值得尝试.
@ElementCollection
@CollectionTable(name="breed_descriptions", joinColumns={ @JoinColumn(name="breed") })
@Column(name="description")
@MapKeyJoinColumn(name="language")
private Map<Language, String> descriptions = new HashMap<>();
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4448 次 |
| 最近记录: |