Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference using @Id and @EmbeddedId for a compound key

Tags:

I've created an entity that uses @Id to point to an @Embeddable compound key. Everything I believe works fine as is. However, after switching @Id to @EmbeddedId everything continues to work fine as far as I can tell.

Before:

@Entity public final class MyEntity {     private CompoundKey id;      @Id     public CompoundKey getId() {         return id;     }      public void setId(CompoundKey id) {         this.id = id;     } 

After:

@Entity public final class MyEntity {     private CompoundKey id;      @EmbeddedId     public CompoundKey getId() {         return id;     }      public void setId(CompoundKey id) {         this.id = id;     } 

Is there a difference between using the @Id and @EmbeddedId annotations when referencing a compound key?

like image 890
digiarnie Avatar asked Oct 05 '10 23:10

digiarnie


People also ask

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.

What is the use of @EmbeddedId?

@EmbeddedId is used for composite primary key. i.e. more than one column behaves jointly as primary key. We need to create an entity as Embeddable and the Embeddable entity can be embedded in other entity to achieve composite primary key.

What is @EmbeddedId in JPA?

Annotation Type EmbeddedIdApplied to a persistent field or property of an entity class or mapped superclass to denote a composite primary key that is an embeddable class. The embeddable class must be annotated as Embeddable .


2 Answers

I'm actually surprised the "before" version is working. According to the specification, the correct way to map your Embeddable compound key is the "after" version. Quoting the JPA 1.0 specification:

2.1.4 Primary Keys and Entity Identity

Every entity must have a primary key.

The primary key must be defined on the entity that is the root of the entity hierarchy or on a mapped superclass of the entity hierarchy. The primary key must be defined exactly once in an entity hierarchy.

A simple (i.e., non-composite) primary key must correspond to a single persistent field or property of the entity class. The Id annotation is used to denote a simple primary key. See section 9.1.8.

A composite primary key must correspond to either a single persistent field or property or to a set of such fields or properties as described below. A primary key class must be defined to represent a composite primary key. Composite primary keys typically arise when mapping from legacy databases when the database key is comprised of several columns. The EmbeddedId and and IdClass annotations are used to denote composite primary keys. See sections 9.1.14 and 9.1.15.

The primary key (or field or property of a composite primary key) should be one of the following types: any Java primitive type; any primitive wrapper type; java.lang.String; java.util.Date; java.sql.Date. In general, however, approximate numeric types (e.g., floating point types) should never be used in primary keys. Entities whose primary keys use types other than these will not be portable. If generated primary keys are used, only integral types will be portable. If java.util.Date is used as a primary key field or property, the temporal type should be specified as DATE.

...

And later:

9.1.14 EmbeddedId Annotation

The EmbeddedId annotation is applied to a persistent field or property of an entity class or mapped superclass to denote a composite primary key that is an embeddable class. The embeddable class must be annotated as Embeddable.

There must be only one EmbeddedId annotation and no Id annotation when the EmbeddedId annotation is used.

like image 119
Pascal Thivent Avatar answered Sep 21 '22 06:09

Pascal Thivent


I referred hibernate docs Hiberate 3.5 annotations reference whereby there is the difference that with @EmbeddedId you can skip annotating the entity class @Embeddable but with @Id it's required.

I tried using @Id without @Embeddable it gives exception:

org.hibernate.mapping.SimpleValue cannot be cast to org.hibernate.mapping.Component

Just this and no extra info like the field or class name.

Well this behavior is as of Hibernate 4; I don't know about other JPA providers. I will test a few and update post accordingly if there are any more findings.

like image 41
baba.kabira Avatar answered Sep 21 '22 06:09

baba.kabira