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все ще може використовуватися в СОЕДИНЕНІЙ стратегії успадкування. Під відповідним розділом специфікації JPA 2.0:

11.1.40 Анотація PrimaryKeyJoinColumn

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

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

...

Якщо жодна PrimaryKeyJoinColumn анотація не вказана для підкласу в стратегії зіставлення JOINED, передбачається, що стовпці зовнішнього ключа мають ті самі імена, що і стовпці первинного ключа первинної таблиці суперкласу.

...

Приклад: підклас "Клієнт" та "Оцінений клієнт"

@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.

Для запису, підтримка Idна OneToOneі ManyToOneбула додана в EclipseLink 1.1 (див це повідомлення від Джеймса Сазерленда , EclipseLink comitter і основний внесок в Java Persistence вікі книги). Але дозвольте мені наполягати, це НЕ є частиною JPA 1.0.


У цьому джерелі weblogs.java.net/blog/felipegaucho/archive/2009/10/24/… зазначено, що використання @ManyToOne та @Id працює з JPA 1.x. Хто зараз правий?
Kawu

ГАРАЗД. Дякуємо за роз'яснення Я маю рацію, що поганий приклад, про який йдеться, використовує @IdClass неправильно? Чи не слід розміщувати анотації @Id в окремих (надлишкових / повторюваних) стовпцях класу сутності, щоб бути правильними? (хоча я знаю, що використовувати @IdClass більше не рекомендується)
Kawu

Я маю на увазі, що в класі повинні бути дві властивості: @Id @Column private String установа; та приватний конкурс струнних @Id @Column; просто вказати PK правильно?
Kawu

@Kawu Вибач, але, чесно кажучи, занадто складно обговорювати це у невеликому вікні коментарів. Я навіть не впевнений, що зрозумів, про що ви говорите. Якщо у вас є інше конкретне запитання, я пропоную або вибрати реалізацію JPA, і трохи поекспериментувати, або опублікувати нове запитання з повним прикладом (і версією JPA). Це значно полегшило б справу.
Pascal Thivent

38

Зазвичай я розрізняю ці два за допомогою цієї схеми:

Використовуйте PrimaryKeyJoinColumn

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

Використовуйте JoinColumn

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


3
@yusher, PrimaryKeyJoinColumnвикористовуйте одне і те ж значення первинного ключа, щоб об'єднати дві таблиці, і JoinColumn, первинний ключ основної таблиці стане зовнішнім ключем в іншій таблиці.
Sam YC

2

Я знаю, що це стара публікація, але хороший час для використання PrimaryKeyColumn, якщо ви хочете односпрямований зв'язок або якщо у вас є кілька таблиць, що мають однаковий ідентифікатор.

Взагалі, це погана ідея, і було б краще використовувати стосунки з іноземними ключами JoinColumn.

Сказавши це, якщо ви працюєте над старою базою даних, яка використовувала подібну систему, тоді був би хороший час для її використання.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.