单向和双向 JPA 以及休眠关联之间有什么区别?

2022-08-31 06:40:19

单向关联和双向关联之间有什么区别?

由于在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;
}

区别在于组是否包含用户的引用。

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


答案 1

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

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

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

  • 您将如何将新的 s 添加到 ?幸运的是,Hibernate在持久化关系时会查看关系的拥有方,因此您只能设置。但是,如果要使内存中的对象保持一致,则还需要添加到 。但是它会使Hibernate从数据库中获取所有元素!UserGroupUser.groupUserGroup.usersGroup.users

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

另请参阅:


答案 2

有两个主要区别。

访问关联方

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

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

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

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

您还需要对双向关联使用添加/删除实用程序方法,以确保两端正确同步

性能

第二个方面与性能有关。

  1. 对于 ,单向关联不如双向关联。@OneToMany
  2. 对于 ,如果 Hibernate 无法判断是否应分配代理或空值,则双向关联将导致父级被紧急获取@OneToOne
  3. 对于 ,集合类型有很大的不同,因为集合列表表现得更好@ManyToMany

推荐