27

what's better for JPA/Hibernate composite primary keys, @IdClass or @EmbeddedId implementations and why?

This is an intentionally naive question. I decided to use @EmbeddedId (for whatever reason) and I feel like I made the wrong choice. Dereferencing the embeddedId that contains the column properties is redundant and quite error-prone when coding.

Are there any more reasons for and/or against the other? Is the a recommendation by the JPA (spec)?

Jens Schauder
  • 77,657
  • 34
  • 181
  • 348
Kawu
  • 13,647
  • 34
  • 123
  • 195

3 Answers3

9

First, if possible, avoid composite ids at all costs. But if you really need, I would recommend @EmbeddedId.

@IdClass is basically a leftover from EJB 2.1 times to make it easier from migrating from BMP. In some other rare corner cases it may be better than @EmbeddedId too. However, generally @EmbeddedId is better and more OO since it encapsulates the concept os the key much better in the object.

You may want to use @AttributeOverride(s) if you need in the key field.

I don't see why do you think that dereferencing the embedded id is redundant and error-prone.

  • Yes, you're right with your last sentence. If one would be using JPA 2.0 syntax, there wouldn't be any redundant fields on the entity class, so you'd have to always dereference the join columns, which seems to be preferable for all 4 composite key vatiants JPA 1.0 @IdClass, JPA 1.0 @EmbeddedId, JPA 2.0 @IdClass, and JPA 2.0 @EmbeddedId. – Kawu Jan 01 '11 at 12:11
  • 1
    Can you explain why composite IDs are bad? – Stefan Falk Jun 28 '15 at 22:03
7

As Pascal wrote here's part of the answer:

Which annotation should I use: @IdClass or @EmbeddedId

In the end, I believe using @IdClass is much easier in practice, because you have to add the embeddedId property name to dereference PK properties, while these aren't written for all non-PK properties.

You always have to remember exactly which properties are part of a PK and those which are not. That complicates writing JPQL queries unneccessarily.

Also, AFAIK the JPA 2.0 spec allows you to put @Id onto @XToX/@JoinColumn/s properties and it introduces the @MapsId annotation, so that mapping identifying relationships (a.k.a. derived identifiers in JPA) are more natural to implement.

Community
  • 1
  • 1
Kawu
  • 13,647
  • 34
  • 123
  • 195
2

I. Remember using idclass to do it. But I'd recommend doing everything you can to avoid multi field keys. They just create extra work.

drekka
  • 20,957
  • 14
  • 79
  • 135
  • Gave +1 'cause it did make us re-evaluate using composite PK and have come to conclusion we'd be much better off w/o them. – Erikson Mar 06 '15 at 18:23
  • 1
    Sometimes - especially when working with a legacy schema - the only way to correctly map an entity is by using composite PKs. Of course when designing a new schema it is better to avoid them (if possible). – snorbi May 12 '17 at 07:46