簡體   English   中英

將java.util.Map與JPA注釋映射時,鍵和值列名覆蓋

[英]Key & value column name overrides when mapping java.util.Map with JPA annotations

我正在研究使用Hibernate 4.1.9和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地圖工作正常,生成的連接表包含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;

但同樣會忽略鍵和值列名稱覆蓋。 有沒有人知道強制執行這些列名覆蓋的方法。

提前致謝...

更新....在查看@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;

使用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;

注意兩種情況被指定為ElementCollection,但是值為另一種實體的兩種情況需要使用ManyToMany。

我正在使用實體作為地圖的關鍵,如下所示。 使用@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<>();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM