In a Spring MVC app using hibernate and JPA, I am trying to set up a mapping for an entity whose underlying data table has a two-column primary key. How can I alter my code below to get it to work?
I created an EmbeddedId called conceptPK
, but I am getting the following error message:
Caused by: org.hibernate.MappingException:
Unable to find column with logical name: conceptPK
in org.hibernate.mapping.Table(sct2_concept) and its related supertables and secondary tables
In the entity class, I set up the primary key with the following code:
@EmbeddedId
@AttributeOverrides({
@AttributeOverride(name="id", column=@Column(name="id")),
@AttributeOverride(name="effectiveTime", column=@Column(name="effectiveTime"))
})
private ConceptPK conceptPK;
The embedded ConceptPK class is as follows:
@Embeddable
class ConceptPK implements Serializable {
@Column(name="id", nullable=false)
protected BigInteger id;
@Column(name="effectiveTime", nullable=false)
@Type(type="org.jadira.usertype.dateandtime.joda.PersistentDateTime")
private DateTime effectiveTime;
/** getters and setters **/
public DateTime getEffectiveTime(){return effectiveTime;}
public void setEffectiveTime(DateTime ad){effectiveTime=ad;}
public void setId(BigInteger id) {this.id = id;}
public BigInteger getId() {return id;}
}
For easier reading, I have uploaded the complete code and the complete stack trace to a file sharing site rather than create an excessively long posting here.
You can read the complete code for the class above
at the file sharing site by clicking on this link.
You can read the code for a second class
that references the first class at this link.
You can read the code for a third class
that references the first class at this link.
You can read the SQL code
that creates the underlying data tables by clicking on this link.
You can read the complete stack trace at the file sharing site by clicking on this link.
Annotating the key as hown below solved the issue for me.
The problem is the
SnomedDescription
Entity's@ManyToOne
association toSnomedConcept
.For a start, this is not a ManyToOne, but in fact a OneToOne, as their primary keys are identical.
But the main problem is that the columns you've used in the
@JoinColumn
annotation for this association do not exist as database columns, so this will never work.Instead, you should have join columns as follows:
Now, you can carry on using the
@ManyToOne
for this relationship, but really you should be using the same embedded PK for both (ConceptPK
), and thenSnomedDescription
will look more like:Yes, you can use the same PK embeddable in multiple Entities.
If it is a one-to-one relationship, then the association in
SnomedConcept
toSnomedDescription
should also be one-to-one, with@PrimaryKeyJoinColumn
.If the association between the two is optional, then the 'side' that is always there should define the one-to-one as
@OneToOne(optional=true)
. In other words, if there is always a Concept, but not always a Description, then the one-to-one in Concept should be defined as@OneToOne(optional=true)
.