Что такое «собственная сторона» в сопоставлении ORM?

Что означает собственно владеющая сторона ? Что объясняет некоторые примеры сопоставления (от одного до многих, от одного до одного, от нескольких до одного )?

Следующий текст является выдержкой из описания @OneToOne в документации Java EE 6. Вы можете видеть в ней концепцию.

Определяет однозначную связь с другим объектом, который имеет множественность один-к-одному. Обычно нет необходимости указывать связанный целевой объект явно, поскольку обычно его можно вывести из типа ссылочного объекта. Если отношение является двунаправленным, сторона, не являющаяся владельцем, должна использовать элемент mappedBy annotations OneToOne, чтобы указать поле отношения или свойство стороны-владельца.

Вы можете себе представить, что владеющая сторона – это сущность, которая имеет ссылку на другую. В вашей отрывке у вас есть отношения «один к одному». Поскольку это симметричное отношение, вы получите то, что если объект A связан с объектом B, то и наоборот.

Это означает, что сохранение в объекте A ссылки на объект B и сохранение в объекте B ссылки на объект A будет избыточным: именно поэтому вы выбираете, какой объект «владеет» другим, имеющим ссылку на него.

Когда у вас есть отношения «один ко многим», объекты, связанные со «большой» частью, будут принадлежать стороне, иначе вам придется хранить много ссылок от одного объекта до множества. Чтобы этого избежать, каждый объект второго classа будет иметь указатель на тот, на который они ссылаются (так что они являются собственностью).

Для отношений «многие-ко-многим», поскольку вам понадобится отдельная таблица сопоставления, в любом случае не будет никакой собственной стороны.

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

Почему необходимо понятие владения:

Идея принадлежности стороне двунаправленного отношения исходит из того факта, что в реляционных базах данных нет двунаправленных отношений, например, в случае объектов. В базах данных мы имеем только однонаправленные отношения – foreign keys.

В чем причина названия «владеющая сторона»?

Собственная сторона отношения, отслеживаемого Hibernate, является стороной отношения, которое владеет внешним ключом в базе данных.

В чем проблема, которую решает идея владения стороной?

Возьмем пример двух объектов, отображаемых без объявления собственной стороны:

 @Entity @Table(name="PERSONS") public class Person { @OneToMany private List idDocuments; } @Entity @Table(name="ID_DOCUMENTS") public class IdDocument { @ManyToOne private Person person; } 

С точки зрения OO это сопоставление определяет не одно двунаправленное отношение, а два отдельных однонаправленных отношения.

Отображение создало бы не только таблицы ID_DOCUMENTS и 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 отношению к ID_DOCUMENTS и дополнительную таблицу ассоциаций.

Чтобы решить эту проблему, нам нужно настроить Hibernate, чтобы остановить отслеживание изменений в отношении Person.idDocuments . Hibernate должен отслеживать только другую сторону отношения IdDocument.person , и для этого мы добавляем mappedBy :

 @OneToMany(mappedBy="person") private List idDocuments; 

Что это значит?

Это означает что-то вроде: «изменения на этой стороне отношения уже сопоставлены другой стороной отношения IdDocument.person, поэтому нет необходимости отслеживать ее здесь отдельно в дополнительной таблице».

Есть ли какие-либо последствия GOTCHA?

Используя mappedBy , если мы вызываем только person.getDocuments().add(document) , внешний ключ в ID_DOCUMENTS НЕ будет привязан к новому документу, потому что это не является собственностью / отслеживаемой стороной отношения!

Чтобы связать документ с новым человеком, вам нужно явно вызвать document.setPerson(person) , потому что это принадлежит стороне отношения.

При использовании mappedBy разработчик должен знать, что является владельцем, и обновлять правильную сторону отношения, чтобы вызвать постоянство нового отношения в базе данных.

  • Список поставщиков Entity Framework для различных баз данных
  • Классы classов Hibernate должны быть Serializable?
  • В чем разница между однонаправленными и двунаправленными ассоциациями JPA и Hibernate?
  • Почему Hibernate не требует конструктора аргументов?
  • JPA CriteriaBuilder - Как использовать оператор сравнения «IN»
  • Как следует использовать равенства и hash-код при использовании JPA и Hibernate
  • Django - id vs pk
  • Почему django prefetch_related () работает только со всеми (), а не с фильтром ()?
  • @Basic (необязательно = false) vs @Column (nullable = false) в JPA
  • Ошибка: java.lang.NoSuchMethodError: org.objectweb.asm.ClassWriter. (I) V
  • Вычисленное свойство с JPA / Hibernate
  • Давайте будем гением компьютера.