Чому потрібне поняття власної сторони:
Ідея власного боку двонаправленого відношення походить від того, що в реляційних базах даних немає двонаправлених відносин, як у випадку з об'єктами. У базах даних ми маємо лише однонаправлені відносини - зовнішні ключі.
У чому причина назви "володіння стороною"?
Сторона, що має відношення, відстежується в сплячому режимі, - це сторона відносини, якій належить зовнішній ключ у базі даних.
Яка проблема, яку вирішує поняття володіння стороною?
Візьмемо приклад двох сутностей, відображених без декларування власного боку:
@Entity
@Table(name="PERSONS")
public class Person {
@OneToMany
private List<IdDocument> idDocuments;
}
@Entity
@Table(name="ID_DOCUMENTS")
public class IdDocument {
@ManyToOne
private Person person;
}
З точки зору ОО, це відображення визначає не одне двонаправлене відношення, а два окремі однонаправлені відносини.
Відображення створило б не тільки таблиці PERSONS
та ID_DOCUMENTS
, але й створило б третю таблицю асоціацій PERSONS_ID_DOCUMENTS
:
CREATE TABLE PERSONS_ID_DOCUMENTS
(
persons_id bigint NOT NULL,
id_documents_id bigint NOT NULL,
CONSTRAINT fk_persons FOREIGN KEY (persons_id) REFERENCES persons (id),
CONSTRAINT fk_docs FOREIGN KEY (id_documents_id) REFERENCES id_documents (id),
CONSTRAINT pk UNIQUE (id_documents_id)
)
Зверніть увагу , що первинний ключ pk
на ID_DOCUMENTS
тільки. У цьому випадку Hibernate відстежує обидві сторони відношення незалежно: Якщо ви додаєте документ у відношення Person.idDocuments
, він вставляє запис у таблицю асоціацій PERSON_ID_DOCUMENTS
.
З іншого боку, якщо ми зателефонуємо idDocument.setPerson(person)
, ми змінимо іноземний ключ person_id на столі ID_DOCUMENTS
. Hibernate створює два однонаправлені (зовнішні ключові) відносини в базі даних, щоб реалізувати одне двостороннє відношення об'єкта.
Як поняття володіння стороною вирішує проблему:
Багато разів то , що ми хочемо тільки зовнішній ключ на столі в ID_DOCUMENTS
стороні PERSONS
і додаткова таблиця асоціації.
Щоб вирішити це, нам потрібно налаштувати Hibernate, щоб припинити відстежувати модифікації відношення Person.idDocuments
. Спящий режим повинен відслідковувати лише іншу сторону відносин IdDocument.person
, і для цього ми додаємо mappedBy :
@OneToMany(mappedBy="person")
private List<IdDocument> idDocuments;
Що означає відображеноBy?
Це означає що - щось на кшталт: «модифікації на цій стороні відносин вже Підключення До
іншій стороні відносин IdDocument.person, тому немає необхідності відстежувати його тут окремо в додатковій таблиці.»
Чи є якісь ГОТЧИ, наслідки?
Використання mappedBy , якщо ми тільки називаємо person.getDocuments().add(document)
, зовнішній ключ в ID_DOCUMENTS
буде НЕ бути пов'язані з новим документом, оскільки це не володіє / гусенична боку відносини!
Щоб зв’язати документ з новою особою, вам потрібно чітко зателефонувати document.setPerson(person)
, оскільки це є власною стороною відносин.
Використовуючи mappedBy , розробник несе обов'язок знати, що є власником, і оновлювати правильну сторону співвідношення, щоб викликати збереження нового відношення в базі даних.