JPA: разница между @JoinColumn и @PrimaryKeyJoinColumn?

83

Какая точная разница между @JoinColumnи @PrimaryKeyJoinColumn?

Вы используете @JoinColumnдля столбцов, которые являются частью внешнего ключа. Типичный столбец может выглядеть так (например, в объединенной таблице с дополнительными атрибутами):

@ManyToOne
@JoinColumn(name = "...")
private OtherClass oc;

Что произойдет, если я сделаю столбец также PK (также идентифицирующим родством)? Поскольку столбец теперь является ПК, я должен пометить его @Id:

@Id
@ManyToOne
@JoinColumn(name = "...")
private OtherClass oc;

Теперь вопрос:

@Id+ Такие @JoinColumnже, как просто @PrimaryKeyJoinColumn?:

@ManyToOne
@PrimaryKeyJoinColumn(name = "...")
private OtherClass oc;

Если нет, то зачем @PrimaryKeyJoinColumn?

Каву
источник

Ответы:

55

Что произойдет, если я сделаю столбец также PK (также идентифицирующим родством)? Поскольку столбец теперь является ПК, я должен пометить его @Id (...).

Эта расширенная поддержка производных идентификаторов фактически является частью нового материала в JPA 2.0 (см. Раздел 2.4.1 «Первичные ключи, соответствующие производным идентификаторам» в спецификации JPA 2.0), JPA 1.0 не допускает Idиспользования OneToOneили ManyToOne. С JPA 1.0 вам нужно будет использовать, PrimaryKeyJoinColumnа также определить Basic Idсопоставление для столбца внешнего ключа.

Теперь вопрос: @Id + @JoinColumn - это то же самое, что просто @PrimaryKeyJoinColumn?

Вы можете получить аналогичный результат , но используя Idна OneToOneили ManyToOneэто намного проще и является предпочтительным способом для сопоставления полученных идентификаторов с JPA 2.0. PrimaryKeyJoinColumnможет по-прежнему использоваться в стратегии наследования JOINED . Ниже соответствующего раздела из спецификации JPA 2.0:

11.1.40 Аннотация PrimaryKeyJoinColumn

В PrimaryKeyJoinColumnаннотации указывается столбец первичного ключа, который используется в качестве внешнего ключа для присоединения к другой таблице.

PrimaryKeyJoinColumnАннотаций используется для соединения основной таблицы подкласса объекта в JOINED стратегии отображения на основной таблице суперкласса; он используется в SecondaryTableаннотации для присоединения вторичной таблицы к первичной таблице; и его можно использовать в OneToOne отображении, в котором первичный ключ ссылающегося объекта используется как внешний ключ для объекта, на который делается ссылка [108] .

...

Если PrimaryKeyJoinColumn аннотация не указана для подкласса в стратегии сопоставления JOINED, предполагается, что столбцы внешнего ключа имеют те же имена, что и столбцы первичного ключа первичной таблицы суперкласса.

...

Пример: подклассы Customer и ValuedCustomer

@Entity
@Table(name="CUST")
@Inheritance(strategy=JOINED)
@DiscriminatorValue("CUST")
public class Customer { ... }

@Entity
@Table(name="VCUST")
@DiscriminatorValue("VCUST")
@PrimaryKeyJoinColumn(name="CUST_ID")
public class ValuedCustomer extends Customer { ... }

[108] Производные механизмы идентификатора, описанные в разделе 2.4.1.1, теперь должны быть предпочтительнее PrimaryKeyJoinColumnдля случая сопоставления OneToOne.

Смотрите также


В этом источнике http://weblogs.java.net/blog/felipegaucho/archive/2009/10/24/jpa-join-table-additional-state говорится, что использование @ManyToOne и @Id работает с JPA 1.x. Кто сейчас прав?

Автор использует предварительную версию EclipseLink, совместимую с JPA 2.0 (версия 2.0.0-M7 на момент написания статьи), чтобы написать статью о JPA 1.0 (!). Эта статья вводит в заблуждение, автор использует то, что НЕ является частью JPA 1.0.

Для справки, поддержка Idon OneToOneи ManyToOneбыла добавлена ​​в EclipseLink 1.1 (см. Это сообщение от Джеймса Сазерленда , разработчика EclipseLink и основного участника вики-книги Java Persistence ). Но позвольте мне настоять на том, что это НЕ часть JPA 1.0.

Паскаль Тивент
источник
В этом источнике weblogs.java.net/blog/felipegaucho/archive/2009/10/24/… говорится, что использование @ManyToOne и @Id работает с JPA 1.x. Кто сейчас прав?
Каву
ХОРОШО. Спасибо, что прояснили это. Я прав, что в упомянутом плохом примере неправильно используется @IdClass? Разве аннотации @Id не должны размещаться в отдельных (повторяющихся / повторяющихся) столбцах в классе сущности, чтобы быть правильным? (хотя я знаю, что использование @IdClass больше не рекомендуется)
Каву
Я имею в виду, что в классе должно быть два свойства: @Id @Column частное учреждение String; и @Id @Column private String соревнование; просто указать ПК правильно?
Каву 06
@Kawu Мне очень жаль, но, честно говоря, слишком сложно обсуждать это в небольшом поле для комментариев. Я даже не уверен, что понял, о чем вы говорите. Если у вас есть другой конкретный вопрос, я предлагаю либо выбрать реализацию JPA и немного поэкспериментировать, либо опубликовать новый вопрос с полным примером (и версией JPA). Это сделало бы все намного проще.
Паскаль Тивент 06
38

Я обычно различаю эти два по этой диаграмме:

Использовать PrimaryKeyJoinColumn

введите описание изображения здесь

Использовать JoinColumn

введите описание изображения здесь

Сэм YC
источник
3
@yusher, PrimaryKeyJoinColumnиспользуйте одно и то же значение первичного ключа для объединения двух таблиц, и JoinColumnпервичный ключ основной таблицы станет внешним ключом в другой таблице.
Sam YC
2

Я знаю, что это старый пост, но лучше всего его использовать PrimaryKeyColumn, если вам нужны однонаправленные отношения или если несколько таблиц имеют один и тот же идентификатор.

В общем, это плохая идея, и было бы лучше использовать отношения внешнего ключа с JoinColumn.

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

Филип Рид
источник