单向和双向JPA和Hibernate关联有什么区别?

hgu*_*ser 122 java orm hibernate jpa associations

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

由于在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;
}
Run Code Online (Sandbox Code Playgroud)

双向关联

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;
}
Run Code Online (Sandbox Code Playgroud)

区别在于该组是否拥有用户的参考.

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

axt*_*avt 137

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

请注意,导航访问并不总是好的,特别是对于"一对多"和"多对多"关系.想象一下Group,包含数千个Users:

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

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

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

也可以看看:


Vla*_*cea 19

主要有两个不同之处.

访问协会方

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

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

如果您具有单向@OneToMany关联,则意味着您只能从外键所在的父端访问该关系.

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

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

性能

第二个方面与绩效有关.

  1. 因为@OneToMany,单向关联的表现不如双向关联.
  2. 因为@OneToOne,如果Hibernate无法判断是否应该分配代理或空值,则双向关联将导致父级被急切地获取.
  3. 因为@ManyToMany,收集类型与Sets表现相比有很大的不同Lists.

  • FK总是站在孩子一边。单向 OneToMany 管理可以位于连接表中的子表中的 FK。请点击链接了解更多详情。 (3认同)
  • 对于多对多,从性能角度来看,它们是单向还是双向并不重要。 (3认同)

Con*_*ger 10

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

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

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

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


kvi*_*sta 9

我不是百分百肯定这是唯一的区别,但它是主要区别.它还建议通过Hibernate文档进行双向关联:

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

特别:

首选双向关联:单向关联更难查询.在大型应用程序中,几乎所有关联都必须可以在查询中双向导航.

我个人对这个一揽子建议有一个小问题 - 在我看来,有些情况下,孩子没有任何实际理由知道其父母(例如,为什么订单项需要知道它的顺序是什么与?)相关联,但我确实看到它在合理的时间内也有价值.而且由于双向性并没有真正伤害任何东西,我认为坚持这一点并不太令人反感.