簡體   English   中英

映射地圖 <Entity, Entity> 該描述符中不存在JPA表中的結果

[英]Mapping a Map<Entity, Entity> in JPA results in table is not present in this descriptor

我需要映射一個Java Map,其中鍵和值都是JPA實體。 我在JPA 2書(Pro JPA 2)中讀到,這應該使用@OneToMany@ManyToMany注釋而不是ElementCollection來完成,因為兩者都是JPA實體。

我可以獲得@ManyToMany批注,可以正常工作,沒有屬性或任何東西。 但是據我了解,這種關系是一對多的。 對於任何值實體,只能有一個包含地圖的類的實體(我在這里正確理解@OneToMany ,因為它與地圖有關?)。

只需使用@OneToMany注釋地圖即可, @OneToMany所示:

@OneToMany
private Map<Stage, ScoreCard> scoreCards;

導致此異常:

[EL Severe]:2018-01-11 21:11:10.755--ServerSession(53937593)-異常[EclipseLink-0](Eclipse Persistence Services-2.7.0.v20170811-d680af5):org.eclipse.persistence.exceptions .IntegrityException描述符

例外情況:

異常[EclipseLink-93](Eclipse Persistence Services-2.7.0.v20170811-d680af5):org.eclipse.persistence.exceptions.DescriptorException異常描述:表[SCORECARD]在此描述符中不存在。 描述符:RelationalDescriptor(fi.ipsc_result_server.domain.ResultData.CompetitorResultData-> [DatabaseTable(COMPETITORRESULTDATA)])

異常[EclipseLink-41](Eclipse Persistence Services-2.7.0.v20170811-d680af5):org.eclipse.persistence.exceptions.DescriptorException異常描述:必須為序列號字段定義非只讀映射。 描述符:RelationalDescriptor(fi.ipsc_result_server.domain.ResultData.CompetitorResultData-> [DatabaseTable(COMPETITORRESULTDATA)])

我發現了許多針對Map的JPA注釋示例,但沒有一個示例能夠說明如何使用實體作為鍵和值來注釋地圖。

這兩個類都使用@Entity進行了注釋,並具有一個ID,可以進行持久化,除非嘗試使該Map持久化,所以問題出在Map的注釋上。

作為測試,我編寫了一個具有Map的測試類:package fi.ipsc_result_server.domain.ResultData;

@Entity
public class TestClass {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    Long id;

    @OneToMany
    @MapKeyJoinColumn(name="testKey")
    Map<TestKeyClass, TestValueClass> testMap;

[getters and setters]
}
package fi.ipsc_result_server.domain.ResultData;
@Entity
public class TestKeyClass {
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    Long id;

[getter and setter for id]
}

package fi.ipsc_result_server.domain.ResultData;

@Entity
public class TestValueClass {
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    Long id;

[getter and setter for id]
}

這將導致相同的異常:

描述符異常:

異常[EclipseLink-93](Eclipse Persistence Services-2.7.0.v20170811-d680af5):org.eclipse.persistence.exceptions.DescriptorException異常描述:表[TESTVALUECLASS]在此描述符中不存在。 描述符:RelationalDescriptor(fi.ipsc_result_server.domain.ResultData.TestClass-> [DatabaseTable(TESTCLASS)])

異常[EclipseLink-41](Eclipse Persistence Services-2.7.0.v20170811-d680af5):org.eclipse.persistence.exceptions.DescriptorException異常描述:必須為序列號字段定義非只讀映射。 描述符:RelationalDescriptor(fi.ipsc_result_server.domain.ResultData.TestClass-> [DatabaseTable(TESTCLASS)])

Map<Entity,Entity>可以與@OneToMany@ManyToMany 您只需要添加一個附加注釋:

@OneToMany
@MapKeyJoinColumn(name="stage")
private Map<Stage, ScoreCard> scoreCards;

名稱是:

映射鍵的外鍵列的名稱。

更新資料

您需要確保值實體具有對鍵實體的引用:

public clas ScoreCard{

  @ManyToOne
  private Stage stage;
}

因此,我通過在地圖的注釋中添加了@JoinColumn而不是@MapKeyJoinColumn來使其工作。 在問題末尾包含的TestClass中,此方法有效,創建了表,並且可以持久保存TestKeyClass實例,因此可以持久保存TestClass實例,因為級聯顯然不包括鍵值實體:

@OneToMany(cascade = CascadeType.PERSIST)
@JoinColumn(name="TESTCOLUMN")
Map<TestKeyClass, TestValueClass> testMap;

所以。 我不知道為什么這樣做,為什么需要它,為什么@MapKeyJoinColumn不起作用。 上面的注釋將生成一個TESTVALUECLASS表,其中包含“ TESTCOLUMN”列(來自@JoinColumn注釋)和“ testMap_KEY”列。 列“ TESTCOLUMN”是TestClass的聯接列,具有TestClass實體(具有映射的類)的ID。 “ testMap_KEY”是TestKeyClass實例的ID,該ID用作特定值的鍵。 所以我想由於某種原因,EclipseLink沒有生成沒有@JoinColumn批注的必需列。

有一次,我通過閱讀並確定自己將在當前項目中很好地掌握JPA,刷新了我對JPA公認的微不足道的知識。 和以前一樣,我對JPA的某些方面一如既往地感到困惑,感覺就像“哦,好了,不管怎么說,它起作用了”……哦,好! 謝謝您的幫助,Maciej!

暫無
暫無

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

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