简体   繁体   English

映射地图 <Entity, Entity> 该描述符中不存在JPA表中的结果

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

I need to map a Java Map where the key and value are both JPA entities. 我需要映射一个Java Map,其中键和值都是JPA实体。 I read in a JPA 2 book (Pro JPA 2) that this should be done with a @OneToMany or @ManyToMany annotation instead of ElementCollection since both are JPA Entities. 我在JPA 2书(Pro JPA 2)中读到,这应该使用@OneToMany@ManyToMany注释而不是ElementCollection来完成,因为两者都是JPA实体。

I can get a @ManyToMany annotation to work without a problem and with no attributes or anything. 我可以获得@ManyToMany批注,可以正常工作,没有属性或任何东西。 But as far as I understand, the relationship is a one-to-many. 但是据我了解,这种关系是一对多的。 For any value entity, there can only be one entity of the class that holds the map (do I understand @OneToMany correctly here as it relates to a Map?). 对于任何值实体,只能有一个包含地图的类的实体(我在这里正确理解@OneToMany ,因为它与地图有关?)。

Simply annotating the map with @OneToMany like so: 只需使用@OneToMany注释地图即可, @OneToMany所示:

@OneToMany
private Map<Stage, ScoreCard> scoreCards;

results in this exception: 导致此异常:

[EL Severe]: 2018-01-11 21:11:10.755--ServerSession(53937593)--Exception [EclipseLink-0] (Eclipse Persistence Services - 2.7.0.v20170811-d680af5): org.eclipse.persistence.exceptions.IntegrityException Descriptor [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描述符

Exceptions: 例外情况:

Exception [EclipseLink-93] (Eclipse Persistence Services - 2.7.0.v20170811-d680af5): org.eclipse.persistence.exceptions.DescriptorException Exception Description: The table [SCORECARD] is not present in this descriptor. 异常[EclipseLink-93](Eclipse Persistence Services-2.7.0.v20170811-d680af5):org.eclipse.persistence.exceptions.DescriptorException异常描述:表[SCORECARD]在此描述符中不存在。 Descriptor: RelationalDescriptor(fi.ipsc_result_server.domain.ResultData.CompetitorResultData --> [DatabaseTable(COMPETITORRESULTDATA)]) 描述符:RelationalDescriptor(fi.ipsc_result_server.domain.ResultData.CompetitorResultData-> [DatabaseTable(COMPETITORRESULTDATA)])

Exception [EclipseLink-41] (Eclipse Persistence Services - 2.7.0.v20170811-d680af5): org.eclipse.persistence.exceptions.DescriptorException Exception Description: A non-read-only mapping must be defined for the sequence number field. 异常[EclipseLink-41](Eclipse Persistence Services-2.7.0.v20170811-d680af5):org.eclipse.persistence.exceptions.DescriptorException异常描述:必须为序列号字段定义非只读映射。 Descriptor: RelationalDescriptor(fi.ipsc_result_server.domain.ResultData.CompetitorResultData --> [DatabaseTable(COMPETITORRESULTDATA)]) 描述符:RelationalDescriptor(fi.ipsc_result_server.domain.ResultData.CompetitorResultData-> [DatabaseTable(COMPETITORRESULTDATA)])

I have found many examples of JPA annotations for Map but none that would show how to annotate a map with entities as key and value. 我发现了许多针对Map的JPA注释示例,但没有一个示例能够说明如何使用实体作为键和值来注释地图。

Both classes are annotated with @Entity and have an Id and can be persisted without problem except for when trying to get this Map persisted, so the problem is with the annotation for the Map. 这两个类都使用@Entity进行了注释,并具有一个ID,可以进行持久化,除非尝试使该Map持久化,所以问题出在Map的注释上。

As a test, I wrote a test class that has a Map: package fi.ipsc_result_server.domain.ResultData; 作为测试,我编写了一个具有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]
}

This results in the same exception: 这将导致相同的异常:

Descriptor Exceptions: 描述符异常:

Exception [EclipseLink-93] (Eclipse Persistence Services - 2.7.0.v20170811-d680af5): org.eclipse.persistence.exceptions.DescriptorException Exception Description: The table [TESTVALUECLASS] is not present in this descriptor. 异常[EclipseLink-93](Eclipse Persistence Services-2.7.0.v20170811-d680af5):org.eclipse.persistence.exceptions.DescriptorException异常描述:表[TESTVALUECLASS]在此描述符中不存在。 Descriptor: RelationalDescriptor(fi.ipsc_result_server.domain.ResultData.TestClass --> [DatabaseTable(TESTCLASS)]) 描述符:RelationalDescriptor(fi.ipsc_result_server.domain.ResultData.TestClass-> [DatabaseTable(TESTCLASS)])

Exception [EclipseLink-41] (Eclipse Persistence Services - 2.7.0.v20170811-d680af5): org.eclipse.persistence.exceptions.DescriptorException Exception Description: A non-read-only mapping must be defined for the sequence number field. 异常[EclipseLink-41](Eclipse Persistence Services-2.7.0.v20170811-d680af5):org.eclipse.persistence.exceptions.DescriptorException异常描述:必须为序列号字段定义非只读映射。 Descriptor: RelationalDescriptor(fi.ipsc_result_server.domain.ResultData.TestClass --> [DatabaseTable(TESTCLASS)]) 描述符:RelationalDescriptor(fi.ipsc_result_server.domain.ResultData.TestClass-> [DatabaseTable(TESTCLASS)])

Map<Entity,Entity> can be used both with @OneToMany and @ManyToMany . Map<Entity,Entity>可以与@OneToMany@ManyToMany You just have to add one additional annotation: 您只需要添加一个附加注释:

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

where name is: 名称是:

The name of the foreign key column for the map key. 映射键的外键列的名称。

Update 更新资料

You need to make sure that the value entity has the reference to the key entity: 您需要确保值实体具有对键实体的引用:

public clas ScoreCard{

  @ManyToOne
  private Stage stage;
}

So I got this to work by adding, not a @MapKeyJoinColumn, but a @JoinColumn to the annotation on the Map. 因此,我通过在地图的注释中添加了@JoinColumn而不是@MapKeyJoinColumn来使其工作。 In the TestClass which I included at the end of my question, this works, the tables are created and I can persist an instance of TestClass, once I have persisted the instance of TestKeyClass since cascading apparently doesn't include the key value entities: 在问题末尾包含的TestClass中,此方法有效,创建了表,并且可以持久保存TestKeyClass实例,因此可以持久保存TestClass实例,因为级联显然不包括键值实体:

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

So. 所以。 I have no idea why this works, why its required and why @MapKeyJoinColumn doesn't work. 我不知道为什么这样做,为什么需要它,为什么@MapKeyJoinColumn不起作用。 The above annotation generates a TESTVALUECLASS table with columns "TESTCOLUMN" (from the @JoinColumn annotation) and "testMap_KEY" column. 上面的注释将生成一个TESTVALUECLASS表,其中包含“ TESTCOLUMN”列(来自@JoinColumn注释)和“ testMap_KEY”列。 Column "TESTCOLUMN" is the join column to TestClass and has the id of the TestClass entity (the class that has the map). 列“ TESTCOLUMN”是TestClass的联接列,具有TestClass实体(具有映射的类)的ID。 "testMap_KEY" is the id of the TestKeyClass instance which serves as the key for the particular value. “ testMap_KEY”是TestKeyClass实例的ID,该ID用作特定值的键。 So I guess for some reason EclipseLink wasn't generating the required columns without the @JoinColumn annotation. 所以我想由于某种原因,EclipseLink没有生成没有@JoinColumn批注的必需列。

At one point I refreshed my admittedly meager knowledge of JPA by reading a bit and figuring I'm going to get a good handle of JPA during my current project. 有一次,我通过阅读并确定自己将在当前项目中很好地掌握JPA,刷新了我对JPA公认的微不足道的知识。 And as has previously been the case, I'm about as perplexed by some of JPA's aspects as always and just feel like "oh well, what ever, it works"... Oh well! 和以前一样,我对JPA的某些方面一如既往地感到困惑,感觉就像“哦,好了,不管怎么说,它起作用了”……哦,好! Thanks for your help, Maciej! 谢谢您的帮助,Maciej!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM