2013-04-20 223 views
25

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

P.S .:我认为如果有人可以解释协会所有者的要点以及双向和单向关联之间的区别,这将有助于解决问题。

回答

43

假设您有订单和订单行。您可以选择订单和订单行之间具有单向的OneToMany(订单将具有OrderLines的集合)。或者你可以选择在OrderLine和Order之间有一个ManyToOne关联(OrderLine会有一个对它的Order的引用)。或者您可以选择同时拥有这两个关联,在这种情况下,关联将成为双向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; 
在订单行

@ManyToOne 
private Order parentOrder; 
1

而且,具有@ManytoOne侧作为所有者仅需要N + 1个q同时保存关联。其中n是协会的数量(许多方面)。

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