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

hmtdttj4  于 2023-01-17  发布在  其他
关注(0)|答案(4)|浏览(186)

单向关联和双向关联有什么区别?
由于在数据库中生成的表都是相同的,所以我发现的唯一区别是双向关联的每一端都有对另一端的引用,而单向关联则没有。

这是单向关联

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;
}

区别在于组是否持有用户的引用。
所以我想知道这是不是唯一的区别?推荐哪种?

jm81lzqq

jm81lzqq1#

主要区别在于双向关系提供了两个方向的导航访问,因此您无需显式查询即可访问另一端。此外,它还允许您将级联选项应用于两个方向。
注意,导航访问并不总是好的,特别是对于“一对多”和“多对多”关系,想象一个Group包含数千个User

  • 您将如何访问它们呢?由于User如此之多,您通常需要应用一些过滤和/或分页,因此无论如何您都需要执行查询(除非你使用collection filtering,这对我来说看起来像是一个黑客)。一些开发人员可能倾向于在这种情况下在内存中应用过滤,这显然对性能不利。注意,拥有这样的关系可以鼓励这类开发人员在不考虑性能影响的情况下使用它。
  • 如何将新的User添加到Group?幸运的是,Hibernate在持久化关系时会查看关系的拥有方,因此您只能设置User.group。然而,如果您希望保持内存中的对象一致,您还需要将User添加到Group.users。但这会使Hibernate从数据库中获取Group.users的所有元素!

因此,我不能同意Best Practices的建议,您需要仔细设计双向关系,考虑用例(您需要双向导航访问吗?)和可能的性能影响。

另见:

8iwquhpp

8iwquhpp2#

有两个主要区别。

访问关联端

第一个与您访问关系的方式有关。对于单向关联,您只能从一端导航关联。
因此,对于单向@ManyToOne关联,这意味着您只能从外键所在的子端访问关系。
如果您有一个单向的@OneToMany关联,这意味着您只能从管理外键的父端访问关系。
对于双向@OneToMany关联,您可以通过两种方式导航关联,从父端或从子端。
您还需要use add/remove utility methods for bidirectional associations to make sure that both sides are properly synchronized

性能

第二个方面与业绩有关。
1.对于@OneToManyunidirectional associations don't perform as well as bidirectional ones
1.对于@OneToOnea bidirectional association will cause the parent to be fetched eagerly if Hibernate cannot tell whether the Proxy should be assigned or a null value
1.对于@ManyToManythe collection type makes quite a difference as Sets perform better than Lists

ykejflvf

ykejflvf3#

我不能100%确定这是唯一的区别,但这是主要的区别。我们也建议Hibernate文档使用双向关联:
http://docs.jboss.org/hibernate/core/3.3/reference/en/html/best-practices.html
具体而言:
首选双向关联:单向关联更难查询。在大型应用程序中,几乎所有关联都必须在查询中的两个方向上都可导航。
我个人对这种笼统的建议有一点小小的意见--在我看来,有些情况下,孩子没有任何实际的理由去了解父母(例如,为什么订单项需要知道与之相关的订单?),但我确实在合理的时间内看到了它的价值。而且,由于双向性并没有真正伤害到任何东西,我不觉得坚持下去有什么不好。

kxeu7u2r

kxeu7u2r4#

就编码而言,双向关系的实现更为复杂,因为根据JPA规范5(第42页),应用程序负责保持双方同步。不幸的是,规范中给出的示例没有给出更多细节,因此它没有给出复杂程度的概念。
当不使用二级缓存时,不正确实现关系方法通常不是问题,因为示例在事务结束时被丢弃。
当使用二级缓存时,如果由于错误地实现了关系处理方法而导致任何东西被破坏,这意味着其他事务也将看到被破坏的元素(二级缓存是全局的)。
正确实现的双向关系可以使查询和代码更简单,但如果它在业务逻辑方面没有实际意义,则不应使用。

相关问题