![](/img/trans.png)
[英]JPA (Hibernate) mapping of Map. What annotations should I use for java.util.Map mapping?
[英]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.