单向和双向 JPA 和 Hibernate 关联之间的区别是什么?

单向关联和双向关联的区别是什么?

由于 db 中生成的表都是相同的,所以我发现的唯一区别是双向关联的每一边都有一个对另一边的引用,而单向的则没有。

这是一个单向联想

public class User {
private int     id;
private String  name;
@ManyToOne
@JoinColumn(
name = "groupId")
private Group   group;
}


public class Group {
private int     id;
private String  name;
}

双向协会

public class User {
private int     id;
private String  name;
@ManyToOne
@JoinColumn(
name = "groupId")
private Group   group;
}
public class Group {
private int         id;
private String      name;
@OneToMany(mappedBy="group")
private List<User>  users;
}

区别在于组是否拥有用户的引用。

所以我想知道这是不是唯一的区别? 这是推荐的?

147058 次浏览

我不是100% 肯定这是 只有的差异,但它是 总台的差异。Hibernate 文档还建议建立双向联系:

Http://docs.jboss.org/hibernate/core/3.3/reference/en/html/best-practices.html

具体来说:

喜欢双向联想: 单向关联更难查询 应用,几乎所有的协会 必须在两个方向都可以通航 查询。

我个人对这个一概而论的建议有一个小小的问题——在我看来,有些情况下,一个孩子没有任何实际的理由去了解他的父母(例如,为什么一个订单项 需要要了解它所关联的顺序但我也看到了其中的价值。而且因为双向性并没有真正伤害到任何东西,所以我不觉得坚持这个观点太令人反感。

主要区别在于,双向关系提供了双向导航访问,因此您可以在不使用显式查询的情况下访问另一端。此外,它还允许您将级联选项应用于两个方向。

注意,导航访问并不总是好的,特别是对于“一对多”和“多对多”关系。想象一个包含数千个 UserGroup:

  • 你要怎么进去?有这么多的 User,您通常需要应用一些过滤和/或分页,因此您无论如何都需要执行查询(除非您使用 集合过滤,对我来说这看起来像是一个技巧)。在这种情况下,一些开发人员可能倾向于在内存中应用筛选,这显然不利于性能。注意,拥有这样的关系可以鼓励这种类型的开发人员使用它,而不考虑性能影响。

  • 你将如何添加新的 UserGroup?幸运的是,Hibernate 在持久化关系时会查看关系的所有方,因此您只能设置 User.group。但是,如果希望保持内存中对象的一致性,还需要将 User添加到 Group.users。但是它会使 Hibernate 从数据库中提取 Group.users的所有元素!

所以,我不能同意 最佳实践的建议。您需要仔细设计双向关系,考虑用例(是否需要双向导航访问?)以及可能的性能影响。

参见:

在编码方面,双向关系的实现更加复杂,因为应用程序负责根据 JPA 规范5(在第42页)保持双方同步。遗憾的是,规范中给出的示例没有提供更多细节,因此它没有给出复杂程度的概念。

当不使用二级缓存时,通常没有正确实现关系方法不是问题,因为实例在事务结束时被丢弃。

在使用二级缓存时,如果由于错误实现的关系处理方法而导致任何内容损坏,这意味着其他事务也会看到损坏的元素(二级缓存是全局的)。

正确实现的双向关系可以使查询和代码更简单,但是如果它在业务逻辑方面没有实际意义,则不应该使用它。

主要有两个不同之处。

访问关联方

第一个是关于如何访问关系。对于单向关联,只能从一端导航关联。

因此,对于单向 @ManyToOne关联,这意味着您只能从外键所在的子端访问关系。

如果有单向 @OneToMany关联,则意味着只能从管理外键的父方访问关系。

对于双向 @OneToMany关联,您可以从父方或子方两种方式导航关联。

你还需要 使用添加/删除实用程序方法进行双向关联,以确保双方正确同步

表演

第二个方面与性能有关。

  1. 对于 @OneToMany单向联想的表现不如双向联想
  2. 对于 @OneToOne如果 Hibernate 无法判断是否应该分配代理或空值,那么双向关联将导致急切地获取父代理
  3. 对于 @ManyToMany集合类型有很大的不同,因为 ABC1的性能比 Lists