В разделе примера @OneToMany
ссылки на аннотацию JPA :
Пример 1-59 @OneToMany - класс клиента с обобщенными данными
@Entity
public class Customer implements Serializable {
...
@OneToMany(cascade=ALL, mappedBy="customer")
public Set<Order> getOrders() {
return orders;
}
...
}
Пример 1-60 @ManyToOne - Класс заказа с родовыми элементами
@Entity
public class Order implements Serializable {
...
@ManyToOne
@JoinColumn(name="CUST_ID", nullable=false)
public Customer getCustomer() {
return customer;
}
...
}
Мне кажется, что Customer
субъект является владельцем ассоциации. Однако в объяснении mappedBy
атрибута в том же документе написано, что:
если отношение является двунаправленным, установите для элемента mappedBy на обратной (не принадлежащей) стороне ассоциации имя поля или свойства, которому принадлежит отношение, как показано в примере 1-60.
Однако, если я не ошибаюсь, похоже, что в примере mappedBy
фактически указывается на стороне-владельце ассоциации, а не на стороне-собственнике.
Итак, мой вопрос в основном:
В двунаправленной (один-ко-многим / многие-к-одному) ассоциации кто из объектов является владельцем? Как мы можем обозначить одну сторону в качестве владельца? Как мы можем назначить Многую сторону владельцем?
Что подразумевается под «обратной стороной ассоциации»? Как мы можем обозначить одну сторону как обратную? Как мы можем обозначить сторону Множество как обратную?
Ответы:
Чтобы понять это, вы должны сделать шаг назад. В ОО заказчику принадлежат заказы (заказы представляют собой список в объекте клиента). Не может быть заказа без клиента. Таким образом, клиент, кажется, является владельцем заказов.
Но в мире SQL один элемент будет фактически содержать указатель на другой. Поскольку для N заказов есть 1 клиент, каждый заказ содержит внешний ключ к клиенту, которому он принадлежит. Это «соединение», и это означает, что заказ «владеет» (или буквально содержит) соединение (информация). Это как раз противоположность мира ОО / модели.
Это может помочь понять:
Обратная сторона является ОО «владельцем» объекта, в данном случае клиентом. У клиента нет столбцов в таблице для хранения заказов, поэтому вы должны указать, где в таблице заказов он может сохранить эти данные (что происходит через
mappedBy
).Другим распространенным примером являются деревья с узлами, которые могут быть как родителями, так и детьми. В этом случае два поля используются в одном классе:
Это объясняет «внешний ключ» проектных работ «многие к одному». Существует второй подход, который использует другую таблицу для поддержания отношений. Это означает, что для нашего первого примера у вас есть три таблицы: одна с клиентами, одна с заказами и таблица с двумя столбцами с парами первичных ключей (customerPK, orderPK).
Этот подход является более гибким, чем описанный выше (он может легко обрабатывать один-к-одному, многие-к-одному, один-ко-многим и даже многие-ко-многим). Цена такая
Вот почему я редко рекомендую такой подход.
источник
@Parent
или@Child
«XtoY» указывала, что означает соединение (а не как оно реализовано )Невероятно, но за 3 года никто не ответил на ваш превосходный вопрос с примерами обоих способов наметить отношения.
Как уже упоминалось, сторона «владелец» содержит указатель (внешний ключ) в базе данных. Вы можете указать любую сторону в качестве владельца, однако, если вы назначите одну сторону в качестве владельца, отношения не будут двунаправленными (обратная сторона, называемая многими, не будет знать своего «владельца»). Это может быть желательно для герметизации / слабой связи:
Единственное решение двунаправленного отображения состоит в том, чтобы сторона «многие» имела свой указатель на «один» и использовала атрибут «mappedBy» @OneToMany. Без атрибута «mappedBy» Hibernate будет ожидать двойного отображения (база данных будет иметь как столбец соединения, так и таблицу соединения, что является избыточным (обычно нежелательным)).
источник
Сущность, которая имеет таблицу с внешним ключом в базе данных, является владельцем-владельцем, а другая таблица, на которую указывают, является обратной сущностью.
источник
Простые правила двунаправленных отношений:
1. Для двунаправленных отношений «многие-к-одному» сторона многих всегда является их владельцем. Пример: 1 комната имеет много человек (человек принадлежит только одной комнате) -> сторона, владеющая человеком
2. Для двунаправленных отношений «один к одному» сторона-владелец соответствует стороне, которая содержит соответствующий внешний ключ.
3. Для двунаправленных отношений «многие ко многим» любая сторона может быть принимающей стороной.
Надежда может помочь вам.
источник
Для двух классов сущностей Customer и Order hibernate создаст две таблицы.
Возможные случаи:
mappedBy не используется в классах Customer.java и Order.java then->
На стороне клиента будет создана новая таблица [name = CUSTOMER_ORDER], в которой будут отображены CUSTOMER_ID и ORDER_ID. Это первичные ключи таблиц клиентов и заказов. На стороне Заказа требуется дополнительный столбец для сохранения соответствующего сопоставления записи Customer_ID.
mappedBy используется в Customer.java [как указано в постановке задачи]. Теперь дополнительная таблица [CUSTOMER_ORDER] не создается. Только один столбец в таблице заказов
mappedby используется в Order.java. Теперь hibernate создаст дополнительную таблицу. [name = CUSTOMER_ORDER] В таблице заказов не будет дополнительного столбца [Customer_ID] для отображения.
Любая сторона может быть сделана владельцем отношений. Но лучше выбрать сторону xxxToOne.
Эффект кодирования -> Только сторона-владелец объекта может изменять статус отношений. В приведенном ниже примере класс BoyFriend является владельцем отношения. даже если подруга хочет расстаться, она не может.
источник
Отношения таблицы против отношений сущности
В системе реляционных баз данных может быть только три типа табличных отношений:
Итак,
one-to-many
табличное отношение выглядит следующим образом:Обратите внимание, что связь основана на столбце внешнего ключа (например,
post_id
) в дочерней таблице.Таким образом, существует единый источник правды, когда речь идет об управлении
one-to-many
отношениями за столом.Теперь, если вы берете двунаправленное отношение сущности, которое отображается в
one-to-many
отношении таблицы, которое мы видели ранее:Если вы посмотрите на диаграмму выше, вы увидите, что есть два способа управления этими отношениями.
В
Post
сущности у вас естьcomments
коллекция:И, в
PostComment
,post
ассоциация отображается следующим образом:Итак, у вас есть две стороны, которые могут изменить ассоциацию сущности:
comments
дочернюю коллекцию, новаяpost_comment
строка должна быть связана с родительскойpost
сущностью через ееpost_id
столбец.post
свойстваPostComment
объектаpost_id
столбец также должен быть обновлен.Поскольку существует два способа представления столбца «Внешний ключ», необходимо определить источник истины, когда дело доходит до перевода изменения состояния ассоциации в эквивалентную модификацию значения столбца «Внешний ключ».
MappedBy (он же обратная сторона)
mappedBy
Атрибут говорит о том , что@ManyToOne
сторона отвечает за управление столбцом внешнего ключа, а коллекция используется только для извлечения дочерних объектов и каскадных родительской сущность изменений состояния детей (например, удаление родителя должен также удалить дочерние объекты).Синхронизировать обе стороны двунаправленной ассоциации
Теперь, даже если вы определили
mappedBy
атрибут и дочерняя сторона@ManyToOne
управляет столбцом внешнего ключа, вам все равно нужно синхронизировать обе стороны двунаправленной ассоциации.Лучший способ сделать это - добавить эти два служебных метода:
addComment
ИremoveComment
методы обеспечения того , чтобы обе стороны синхронизированы. Таким образом, если мы добавляем дочернюю сущность, дочерняя сущность должна указывать на родителя, а родительская сущность должна иметь дочерний объект, содержащийся в дочерней коллекции.источник