Hibernate / JPA ManyToOne与OneToMany

时间:2013-04-20 10:58:16

标签: hibernate java-ee jpa one-to-many many-to-one

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

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

4 个答案:

答案 0 :(得分:53)

假设您有订单和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;
在OrderLine中

@ManyToOne
private Order parentOrder;

答案 1 :(得分:3)

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

虽然以tbl_CreateFreeBet作为所有者,而插入具有关联的父实体(一侧)(多方)将导致2 * N + 1个查询。其中一个查询用于插入关联,而其他查询用于更新关联实体中的外键。

答案 2 :(得分:0)

我会举例说明,假设您有一个针对订单或POS系统的设计,那么每个订单都有订单明细(产品)。在这种情况下,我们有一个@onetomany关系,对于销售和销售明细关系。如果我有一个用户表,并且每个用户都绑定到一个特定商店,那么我们可以有很多用户绑定到同一家商店,因此@manytoone

答案 3 :(得分:0)

尽管以上答案是准确的,但我将以另一种方式给出答案。

@OneToMany@ManyToOne分为两个部分;左部分和右部分。 例如; @OneToMany = 'One'是左部分,“ Many”是右部分,@ManyToOne = 'Many'是左部分,“ One”是右部分。

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

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