2013-04-20 2 views
25

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

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

ответ

43

Предположим, у вас есть заказ и заказ. Вы можете выбрать однонаправленную 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; 
1

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

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

Смежные вопросы