Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JPA/Hibernate: What's better for composite primary keys, @IdClass or @EmbeddedId implementations and why? [duplicate]

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)?

like image 205
Kawu Avatar asked Oct 26 '10 14:10

Kawu


People also ask

How does JPA implement composite primary key?

In JPA, we have two options to define the composite keys: the @IdClass and @EmbeddedId annotations. In order to define the composite primary keys, we should follow some rules: The composite primary key class must be public. It must have a no-arg constructor.

How does Hibernate handle composite keys?

A composite primary key is mapped using an Embeddable type in hibernate. We'll first create an Embeddable type called EmployeeIdentity containing the employeeId and companyId fields, and then create the Employee entity which will embed the EmployeeIdentity type.

Can we use composite keys in Hibernate?

Use embeddable objects to join two primary keys into one composite key. Every JPA entity has a primary key, but some entities have more than one value as their primary key. In this case, you need to use a composite key. This Java tip introduces you to using composite keys in JPA and Hibernate.

Which of the following is the correct use case for @EmbeddedId annotation?

The use of @Id with a class marked as @Embeddable is the most natural approach. The @Embeddable tag can be used for non-primary key embeddable values anyway. It allows you to treat the compound primary key as a single property, and it permits the reuse of the @Embeddable class in other tables.


2 Answers

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.

like image 91
Victor Stafusa Avatar answered Sep 20 '22 17:09

Victor Stafusa


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.

like image 29
Kawu Avatar answered Sep 20 '22 17:09

Kawu