关键&使用JPA注释映射java.util.Map时,值列名覆盖

时间:2014-06-10 10:30:43

标签: java hibernate jpa dictionary annotations

我正在研究使用Hibernate 4.1.9& amp; JPA注释。

如果我想存储一个Map,其中键是实体值的属性,则标记看起来像这样

    @OneToMany(mappedBy = "deptById", targetEntity = com.demo.impls.Employee.class)
    @MapKey(name = "entityId")
    private Map<Long, Employee> employeesById;

请注意,上面的标记不会创建连接表,但是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;

在这些情况下,钥匙和钥匙之间没有关系。和价值也没有与持有实体有任何关系。 我必须能够指定连接表的名称以及键和列的列名称。值。

我试过以下

@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;

案例0地图工作正常&amp;生成的连接表具有DEPARTMENT,VALUE,KEY

其他三种情况的工作方式与在表格中存储数据的程度相同。在Java中使用相关的键/值&amp;来询问表格。取回预期的结果 - 即它确实使用@ElementCollection

处理存储实体

但是列名使用@Column覆盖(name =&#34; value&#34;)&amp;当键或值是实体时,将忽略@MapKeyColumn(name =&#34; key&#34;)。

我尝试使用@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;

但是关键&amp;值列名覆盖将被忽略。有没有人知道如何强制执行这些列名覆盖。

提前致谢...

UPDATE ....在查看@wypieprz的响应后,我想我知道正确的注释,允许您为值&amp;指定列名称。当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;

使用inverseJoinColumn我可以指定值列名。

但是如果密钥是实体,我还没有找到指定密钥列名称的方法。正如医生所说@MapKeyColumn&#34;指定地图的键列的映射,其地图键是基本类型&#34;

当密钥是实体和密钥时,我也不确定要使用的注释。价值是基本的。使用ManyToMany只是不起作用&amp;我想我可能不得不使用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;

注意两个案例被指定为ElementCollection,但两个案例的值是另一个实体需要使用ManyToMany。

1 个答案:

答案 0 :(得分: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<>();