Разница с использованием @Id и @EmbeddedId для составного ключа

Я создал объект, который использует @Id для указания сложного ключа @Embeddable. Все, что я считаю, прекрасно работает. Однако после переключения @Id на @EmbeddedId все продолжает работать нормально, насколько я могу судить.

До:

@Entity
public final class MyEntity {
    private CompoundKey id;

    @Id
    public CompoundKey getId() {
        return id;
    }

    public void setId(CompoundKey id) {
        this.id = id;
    }

После того, как:

@Entity
public final class MyEntity {
    private CompoundKey id;

    @EmbeddedId
    public CompoundKey getId() {
        return id;
    }

    public void setId(CompoundKey id) {
        this.id = id;
    }

Есть ли разница между использованием аннотаций @Id и @EmbeddedId при ссылке на составной ключ?

Ответ 1

Я действительно удивлен , прежде чем " версия работает. Согласно спецификации, правильный способ сопоставления вашего составного ключа Embeddable - " после версии. Указание спецификации JPA 1.0:

2.1.4 Первичные ключи и идентификатор сущности

Каждый объект должен иметь первичный ключ.

Первичный ключ должен быть определен на объект, который является корнем объекта иерархии или на сопоставленном суперклассе иерархию сущности. Первичный ключ должен быть определен точно один раз в иерархии объектов.

Простой (то есть некомпозитный) первичный ключ должен соответствовать одному постоянное поле или свойство класс сущности. Аннотация Idиспользуется для обозначения простого первичного ключа.См. Раздел 9.1.8.

Составной первичный ключ должен соответствуют одному постоянное поле или свойство или набор таких полей или свойств, как описано ниже. Класс первичного ключа должны быть определены для представления составной первичный ключ. композитный первичные ключи обычно возникают, когда сопоставление из устаревших баз данных, когда ключ базы данных состоит из нескольких колонны. EmbeddedId и IdClass аннотации используются для обозначают составные первичные ключи. Видеть разделы 9.1.14 и 9.1.15.

Первичный ключ (или поле или свойство составного первичного ключа) должно быть один из следующих типов: любая Java примитивный тип; любая примитивная обертка тип; java.lang.String; java.util.Date; java.sql.Date. В общий, однако, приблизительный числовой типы (например, типы с плавающей запятой) никогда не должны использоваться в первичных ключах. Объекты, чьи первичные ключи используют типы кроме них, они не будут переносимыми. Если сгенерированные первичные ключи используются только интегральные типы портативный. Если java.util.Date используется как поле или свойство первичного ключа, временный тип должен быть указан как DATE.

...

И позже:

9.1.14 EmbeddedId Аннотация

Используется аннотация EmbeddedIdк постоянному полю или свойству класс сущности или сопоставленный суперкласс для обозначения составного первичного ключа, который является вложенным классом. Встраиваемый класс должен быть аннотирован как Embeddable.

Должен быть только один EmbeddedIdаннотации и без аннотации Id, когда используется аннотация EmbeddedId.

Ответ 2

Это слишком поздно для этого ответа, но в случае, если это поможет.

Я ссылался на hibernate docs Ссылка на аннотации Hiberate 3.5, в соответствии с которой существует разница, которая с @EmbeddedId позволяет пропустить аннотацию класса сущности @Embeddable но с @Id его необходимо.

Я попытался использовать @Id без @Embeddable, он дает исключение:

org.hibernate.mapping.SimpleValue не может быть передан в org.hibernate.mapping.Component

Только это и никакая дополнительная информация, как поле или имя класса.

Хорошо, это поведение относится к Hibernate 4; Я не знаю о других провайдерах JPA. Я буду проверять несколько и обновлять сообщение соответственно, если есть еще какие-либо выводы.

Надеюсь, это поможет кому-то!