Табличні відносини проти відносин сутності
У системі реляційних баз даних може бути лише три типи зв’язків таблиць:
- один на багато (через стовпець із зовнішнім ключем)
- один на один (за допомогою спільного первинного ключа)
- багато-до-багатьох (через таблицю посилань з двома іноземними ключами, що посилаються на дві окремі батьківські таблиці)
Отже, співвідношення one-to-many
таблиці виглядає так:
Зауважте, що взаємозв'язок заснований на стовпці "Зовнішній ключ" (наприклад, post_id
) у дочірній таблиці.
Отже, є єдине джерело істини, коли мова йде про управління one-to-many
відносинами таблиці.
Тепер, якщо ви берете двонаправлене відношення сутності, яке відображає на one-to-many
таблиці відносини, які ми бачили раніше:
Якщо ви подивитеся на діаграму вище, ви побачите, що є два способи управління цим взаємозв'язком.
У Post
сутності ви маєте comments
колекцію:
@OneToMany(
mappedBy = "post",
cascade = CascadeType.ALL,
orphanRemoval = true
)
private List<PostComment> comments = new ArrayList<>();
І, в PostComment
, то post
об'єднання відображається наступним чином :
@ManyToOne(
fetch = FetchType.LAZY
)
@JoinColumn(name = "post_id")
private Post post;
Отже, у вас є дві сторони, які можуть змінити асоціацію об'єктів:
- Додавши запис у
comments
дочірню колекцію, новий post_comment
рядок повинен бути пов’язаний із материнським post
об'єктом через його post_id
стовпець.
- Встановивши
post
властивість PostComment
сутності, post_id
стовпець також повинен бути оновлений.
Оскільки є два способи подання стовпця "Зовнішній ключ", ви повинні визначити, що є джерелом істини, коли мова заходить про перетворення зміни стану асоціації у його еквівалентну модифікацію значення стовпця "Зовнішній ключ"
MappedBy (він же зворотний бік)
mappedBy
Атрибут говорить про те , що @ManyToOne
сторона відповідає за управління стовпцем зовнішнього ключа, а колекція використовується тільки для вилучення дочірніх об'єктів і каскадних батьківської сутність змін стану дітей (наприклад, видалення батька повинен також видалити дочірні об'єкти).
Його називають зворотною стороною, оскільки вона посилається на властивість дочірньої сутності, яка управляє цим співвідношенням таблиці.
Синхронізуйте обидві сторони двостороннього об'єднання
Тепер, навіть якщо ви визначили mappedBy
атрибут і @ManyToOne
асоціація на стороні дитини керує стовпцем Іноземний ключ, вам все одно потрібно синхронізувати обидві сторони двонаправленої асоціації.
Найкращий спосіб зробити це - додати ці два корисні методи:
public void addComment(PostComment comment) {
comments.add(comment);
comment.setPost(this);
}
public void removeComment(PostComment comment) {
comments.remove(comment);
comment.setPost(null);
}
Методи addComment
та removeComment
методи забезпечують синхронізацію обох сторін. Отже, якщо ми додамо дочірнє ціле, то дочірнє сутність повинно вказувати на батьків, і материнське підприємство повинно мати дитину, що міститься в дочірній колекції.
Щоб отримати докладнішу інформацію про найкращий спосіб синхронізувати всі двонаправлені типи асоціацій, перегляньте цю статтю .