Табличні відносини проти відносин сутності
У системі реляційних баз даних може бути лише три типи зв’язків таблиць:
- один на багато (через стовпець із зовнішнім ключем)
- один на один (за допомогою спільного первинного ключа)
- багато-до-багатьох (через таблицю посилань з двома іноземними ключами, що посилаються на дві окремі батьківські таблиці)
Отже, співвідношення 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методи забезпечують синхронізацію обох сторін. Отже, якщо ми додамо дочірнє ціле, то дочірнє сутність повинно вказувати на батьків, і материнське підприємство повинно мати дитину, що міститься в дочірній колекції.
Щоб отримати докладнішу інформацію про найкращий спосіб синхронізувати всі двонаправлені типи асоціацій, перегляньте цю статтю .