Hibernate/JPA ManyToOne与OneToMany

arj*_*soh 40 hibernate jpa one-to-many many-to-one java-ee

我正在阅读Hibernate关于实体关联的文档,我遇到了一些困难来弄清楚一些事情.它本质上必须ManyToOneOneToMany关联之间的区别.虽然我在实际项目中使用它们,但我无法完全理解它们之间的差异.据我了解,如果一个表/一个实体ManyToOne与另一个表有关联,那么该关联应该来自另一方OneToMany.那么,我们应该如何根据具体情况决定选择哪一个,以及它如何影响数据库/查询/结果?到处都有一个很好的例子吗?

PS:我认为由于它与问题的相关性会有所帮助,如果有人可以解释关联所有者的意义以及双向和单向关联之间的区别.

JB *_*zet 56

假设您有订单和OrderLine.您可以选择在Order和OrderLine之间使用单向OneToMany(Order将具有OrderLines的集合).或者您可以选择在OrderLine和Order之间建立ManyToOne关联(OrderLine将引用其订单).或者您可以选择同时使用两者,在这种情况下,关联将成为双向OneToMany/ManyToOne关联.

您选择的解决方案主要取决于具体情况以及实体之间的耦合程度.例如,如果用户,公司,提供商都有许多地址,那么在每个地址和地址之间保持单向是有意义的,并且地址不知道他们的所有者.

假设您有一个用户和一个消息,用户可以拥有数千条消息,将消息模型设置为消息到用户的ManyToOne是有意义的,因为您无论如何都很少要求用户的所有消息.虽然JPQL查询通过浏览其关联来加入实体之间,但关联可以是双向的,仅用于帮助查询.

在双向关联中,您可能处于对象图形不一致的情况.例如,订单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;
Run Code Online (Sandbox Code Playgroud)

在OrderLine中:

@ManyToOne
private Order parentOrder;
Run Code Online (Sandbox Code Playgroud)


Gig*_*hew 19

虽然上面的答案是准确的,但我将以不同的方式呈现答案。

@OneToMany都有@ManyToOne两个部分;左部分和右部分。例如:

  • @OneToMany=“一个”是左边部分,“许多”是右边部分
  • @ManyToOne=“Many”是左侧部分,“One”是右侧部分

使用这种理解的关联的简单规则是,左侧部分代表您在其中定义关联的类。

因此,如果您@ManyToOne在 OrderLine 类中定义引用 Order 类,则意味着许多 OrderLine 关联到一个 Order 类。


小智 9

此外,将@ManytoOneside 作为所有者将在保存关联时只需要 n+1 次查询。其中 n 是关联的数量(多方)。

@OneToMany作为所有者,同时插入具有关联(多方)的父实体(一侧)将导致 2*N + 1 次查询。其中一个查询将用于插入关联,而另一个查询将用于更新关联实体中的外键。