繁体   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