Разница в использовании @Id и @EmbeddedId для составного ключа - PullRequest
17 голосов
/ 06 октября 2010

Я создал объект, который использует @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 при ссылке на составной ключ?

Ответы [ 2 ]

28 голосов
/ 06 октября 2010

Я на самом деле удивлен, что "до" версии работает.Согласно спецификации, правильный способ сопоставления вашего составного ключа 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 используется в качестве поля или свойства первичного ключа, временной тип должен быть указан как ДАТА.

...

и более поздние:

9.1.14 Аннотация EmbeddedId

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

При использовании аннотации EmbeddedId должна быть только одна аннотация EmbeddedId и Id.

14 голосов
/ 23 марта 2012

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

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

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

org.hibernate.mapping.SimpleValue нельзя преобразовать в org.hibernate.mapping.Component

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...