Which annotation should I use: @IdClass or @EmbeddedId
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 {
@EmbeddedId 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 e.name from Employee e
and with @EmbeddedId
you have to write:
select e.employeeId.name from Employee e
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.
There are three strategies to use a compound primary key:
- Mark it as
@Embeddable
and add to your entity class a normal property for it, marked with@Id
. - Add to your entity class a normal property for it, marked with
@EmbeddedId
. - Add properties to your entity class for all of its fields, mark them with
@Id
,and mark your entity class with@IdClass
, supplying the class of your primary key class.
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.
The next most natural approach is the use of the @EmbeddedId
tag. Here, the primary key class cannot be used in other tables since it is not an @Embeddable
entity, but it does allow us to treat the key as a
single attribute of some class.
Finally, the use of the @IdClass
and @Id
annotations allows us to map the compound primary key class using properties of the entity itself corresponding to the names of the properties in the primary key class. The names must correspond (there is no mechanism for overriding this), and the primary key class must honor the same obligations as with the other two techniques. The only advantage to this approach is its ability to “hide” the use of the primary key class from the interface of the enclosing entity. The @IdClass
annotation takes a value parameter of Class type, which must be the class to be used as the compound primary key. The fields that correspond to the properties of the primary key class to be used must all be annotated with @Id
.
Reference: http://www.apress.com/us/book/9781430228509