[hibernate-dev] Cache key containing composite ID with a many-to-one

Steve Ebersole steve at hibernate.org
Thu Dec 5 08:13:51 EST 2019


A few things...

On Thu, Dec 5, 2019 at 1:17 AM Yoann Rodiere <yoann at hibernate.org> wrote:

Embedded IDs containing an association are a monstrosity anyway, and
> lead to problems even on the user side.
> E.g. you can't serialize (to a String, JSON, ...) and more importantly
> deserialize such ID without a session, in particular when using IDs in URL
> paths or in JSON content.
>

I disagree to an extent here.  Assuming I think composite ids are a good
idea anyway (I dont) then I actually think this is the most natural way to
model this.  I personally think JPA's MapsId is the monstrosity here ;)
FWIW however, JPA does not define support for @EmbeddedId with
a @ManyToOne.  So in that sense we'd be "ok" simply saying "ok, we support
mapping those, but they cannot be cached" if we need to go that route.

We already support a form of loading an entity with MapsId using the basic
form of the associated id if the associated entity as just a simple id.
It's not a stretch to extend that to composite ids I think which would be a
good feature.  Consider:

@Entity
public class Person {
  @Id String ssn;

  ...
}

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

  ...
}

You can load a MedicalHistory here using the Person id.  E.g.
`session.get( MedicalHistory.class,
"123-45-6789" );`

If you consider a case like:

@Entity
@IdClass(EmployeeId.class)
public class Employee {
  @Id String firstName
  @Id String lastName

  ...
}

public class DependentId {
  String name;
  EmployeeId emp;
}

@Entity
@IdClass(DependentId.class)
public class Dependent {
  @Id String name;
  @Id
  @JoinColumns({
    @JoinColumn(name="FK1", referencedColumnName="firstName"),
    @JoinColumn(name="FK2", referencedColumnName="lastName")
  })
  @ManyToOne Employee emp;

  ...
}

It would be nice to allow loading a Dependent like: `session.load(
Dependent.class,
new Object[] {"Steve","Ebersole"} );`  The trouble there is the ordering of
the values compared to the attribute order.

This is all beyond the original question, but your point about loading
these made me think about this.  Ofc serializing does not disassemble, so
this is a moot point in regards to that.  For JSON, depends on your
marshalling


For these IDs to make sense, we would need to force users to define a
> separate, association-free class (using @IdClass?) to represent the
> "serializable" form of the embedded ID, which would also be used in
> Session.find() et. al. This would probably help when it comes to caching,
> too.
>

JPA does not allow mixing of @IdClass and @EmbeddedId.  But I think that's
a valid option.  In fact in our original work on 6 where we completely
replaced the mapping model (persisters) i had added support for this.  We
could add an improvement to pull this feature to 6 proper?


More information about the hibernate-dev mailing list