I need to map a Java Map where the key and value are both JPA entities. 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.
I can get a @ManyToMany
annotation to work without a problem and with no attributes or anything. 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?).
Simply annotating the map with @OneToMany
like so:
@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
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. Descriptor: 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. Descriptor: 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.
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.
As a test, I wrote a test class that has a 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. Descriptor: 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. Descriptor: RelationalDescriptor(fi.ipsc_result_server.domain.ResultData.TestClass --> [DatabaseTable(TESTCLASS)])