views:

4262

answers:

2

The JPA (Java Persistence API) specification has 2 different ways to specify entity composite keys: @IdClass and @EmbeddedId.

I'm using both annotations on my mapped entities, but it turns out to be a big mess to people who aren't very familiar with JPA.

I want to adopt only one way to specify composite keys. Which one is really the best? Why?

+5  A: 

I consider that EmbeddedId is probably more verbose because with IdClass you cannot access the entire primary key object using any field access operator. Using the EmbeddedId you can do like this:

@Embeddable class EmployeeId { name, dataOfBirth }
@Entity class Employee {
  @Embedded EmployeeId employeeId;
  ...
}

This gives a clear notion of the fields that make the composite key because they are all aggregated in a class that is accessed trough a field access operator.

Another difference with IdClass and EmbeddedId is when it comes to write HQL.

With IdClass you write:

select c.ClientId from Customer c

and with EmbeddedId you have to write:

select c.MyPk.ClientId from Customer c

You have to write more text for the same query. Some may argue that this differs from a more natural language like the one promoted by IdClass. But most of the times understanding right from the query that a given field is part of the composite key is of invaluable help.

smink
+1  A: 

I discovered an instance where I had to use EmbeddedId in favor of IdClass. In this scenario there a join table that has additional columns defined. I attempted to solve this problem using IdClass to represent the key of an entity that explicitly represents rows in the join table. I couldn't get it working this way. Thankfully "Java Persistence With Hibernate" has a section dedicated to this topic. One proposed solution was very similar to mine but it used EmbeddedId instead. I modeled my objects after those in the book it now behaves correctly.

laz