[hibernate-dev] Metamodel - Entity primary key mappings

Steve Ebersole steve at hibernate.org
Mon Apr 7 11:27:37 EDT 2014


I've been spending a lot of time the last 2 weeks trying to get a good
"mental model" as to how to best model the information pertaining to an
entity's primary key.  Most of this effort went into trying to understand
JPA's "derived identity" support.

First and foremost I want to get away from modelling this (in the
metamodel) as a singular attribute. This is unnatural in the
"non-aggregated composite id" case forcing us to build a "virtual"
attribute.  I think that this is very doable with the distinction I
recently added to the metamodel between Embedded/Embeddable.

Next is to finish up support for IdClass, which should be close to done.
 Gail, I know you had mentioned a case where that support was lacking.
 Could you send me the specifics so I make sure we get that case covered?

Beyond that is mainly incorporating support for JPA "derived identities".
 With that, I want to share some of my understanding and see if I missed
anything...

"Derived identity" support is essentially Hibernate's much older "foreign"
identifier generator, namely that the child entity gets (all of or part of)
its identifier from a to-one association defined on it, from its "foreign
key" value.  But of course the spec verbosely covers all the ways this
might happen.

The very first thing I noticed is that the examples in the spec come in 2
distinct top-level flavors.  Examples 1-3 are cases where the "parent id"
is simply part of the "derived (child) id".  Examples 4-6 are cases where
the parent id *is* the child id (shared pk).  I am not sure how important
this distinction is in practice, but I also noticed that @MapsId is only
pertinent wrt the second set of cases where we have the shared pk.  This
was the first time I have noticed that distinction.

The one monkey wrench that JPA throws into the works here is that there are
essentially multiple views of an entity's PK.  As one example, take the
spec's "Example 4.a":

@Entity
public class Person {
  @Id String ssn;
  ...
}

@Entity
public class MedicalHistory {
  @Id
  @OneToOne
  @JoinColumn(name="FK")
  Person patient;
  ...
}

Ultimately, the primary key of MedicalHistory is the `ssn` of its
associated Person.  Thus both of these are valid:

entityManager.find( MedicalHistory.class, somePerson );
entityManager.find( MedicalHistory.class, somePerson.ssn );

For those who have seen it, this is the reason for the wonkiness inside
Hibernate's runtime engine wrt incoming id type while doing a load.


I am still going through all the use cases (ours plus JPA) to make sure we
get everything covered.  But I wanted to hopefully get some discussion
started around this and get any thoughts y'all might have.


More information about the hibernate-dev mailing list