Hibernate / JPA ManyToOne против OneToMany

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

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

2 ответов


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

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

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

в двунаправленной ассоциации вы можете оказаться в ситуации, когда график объектов непоследователен. Например, порядок A будет иметь пустой набор строк порядка, но некоторые строки порядка будут иметь ссылку на порядок 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;

in OrderLine :

@ManyToOne
private Order parentOrder;

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

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