Подтвердить что ты не робот

Hibernate/JPA ManyToOne против OneToMany

В настоящее время я читаю документацию Hibernate относительно ассоциаций сущностей, и я немного затрудняюсь понять некоторые вещи. Это должно быть сделано по существу с разницей между ассоциациями ManyToOne и OneToMany. Хотя я использовал их в реальных проектах, я не могу полностью понять разницу между ними. Насколько я понимаю, если таблица/сущность имеет связь ManyToOne с другой, то ассоциация должна быть с другой стороны OneToMany. Итак, как нам решить, какой из них выбрать на основе конкретного случая и как он влияет на базу данных/запросы/результаты? Есть ли повсюду хороший пример?

P.S.: Я считаю, что это было бы полезно из-за его актуальности для вопроса, если бы кто-то мог, кроме того, объяснить, что является точкой владельца ассоциации и разницы между двунаправленной и однонаправленной ассоциацией.

4b9b3361

Ответ 1

Предположим, что у вас есть Ордер и OrderLine. Вы можете выбрать однонаправленную OneToMany между Order и OrderLine (у Order будет коллекция OrderLines). Или вы можете выбрать связь ManyToOne между OrderLine и Order (OrderLine будет иметь ссылку на свой Ордер). Или вы можете выбрать оба варианта, и в этом случае ассоциация становится двунаправленной ассоциацией OneToMany/ManyToOne.

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

Предположим, что у вас есть Пользователь и Сообщение, где у пользователя могут быть тысячи сообщений, может иметь смысл моделировать его только как ManyToOne от Message to User, потому что вы редко запрашиваете все сообщения пользователя так или иначе. Связь может быть сделана двунаправленной только для помощи в запросах, поскольку, поскольку запросы JPQL соединяются между объектами путем навигации по их ассоциациям.

В двунаправленной связи вы можете оказаться в ситуации, когда график объектов несовместим. Например, Order A будет иметь пустой набор OrderLines, но некоторые OrderLines будут иметь ссылку на заказ A. JPA налагает обязательство всегда иметь одну сторону ассоциации, являющуюся стороной владельца, а другая сторона является обратной стороной. Обратная сторона игнорируется JPA. Сторона владельца - это сторона, которая решает, какое отношение существует. В двунаправленной ассоциации OneToMany сторона владельца должна быть большой стороной. Таким образом, в предыдущем примере сторона владельца была бы OrderLine, и JPA сохраняла бы связь между строками и порядком A, поскольку строки имеют ссылку на A.

Такая ассоциация будет отображаться следующим образом:

в порядке:

@OneToMany(mappedBy = "parentOrder") // mappedBy indicates that this side is the 
   // inverse side, and that the mapping is defined by the attribute parentOrder 
   // at the other side of the association.
private Set<OrderLine> lines;

в OrderLine:

@ManyToOne
private Order parentOrder;

Ответ 2

Кроме того, наличие стороны @ManytoOne в качестве владельца потребует только n + 1 запросов при сохранении ассоциаций. Где n - количество ассоциаций (много сторон).

Принимая во внимание, что @OneToMany как владелец, при вставке родительского объекта (с одной стороны) с ассоциациями (много сторон) приведет к 2 * N + 1 запросам. В котором один запрос был бы для вставки ассоциации, а другой запрос - для обновления внешнего ключа в связанном объекте.