Skip to content
Advertisement

Difference using @Id and @EmbeddedId for a compound key

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?

Advertisement

Answer

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.

User contributions licensed under: CC BY-SA
6 People found this is helpful
Advertisement