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

因为在数据库中生成的表都是相同的,所以我发现唯一的区别是双向关联的两边都会有一个指向另一个的引用,而单向的则不会.

This is a Unidirectional association

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

The Bidirectional association

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

区别在于该组是否持有该用户的引用.

所以我想知道这是唯一的不同之处吗?推荐哪一种?

推荐答案

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

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

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

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

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

See also:

Java相关问答推荐

使用Apache Poi MQLSlideShow,在XSLFTable表中,我们可以在文本段落后面的每个单元格中包含圆角矩形吗?

Java取消任务运行Oracle查询通过JDBC—连接中断,因为SQLSTATE(08006),错误代码(17002)IO错误:套接字读取中断

如何在带有Micronaut的YAML中使用包含特殊字符的字符串作为键

调用引发泛型异常的泛型方法时出现编译错误

Com.example.service.QuestionService中的构造函数的参数0需要找不到的类型为';com.example.Dao.QuestionDao;的Bean

没有使用Lombok生成的参数

FETCH类型设置为LAZY,但它仍会发送第二个请求

使用SWIG将C++自定义单元类型转换为基本Java类型

插入中的JOOQ序列,设置为VS值

嘲笑黄瓜中的对象

Oracle中从JSON中提取和插入数据

在Oracle中调用输出参数在索引处缺少IN或OUT参数的函数

在具有Quarkus Panache的PostgreSQL中将JSON数据存储为JSONB时,会将其存储为转义字符串

Java CDI:@Singleton@Startup@Inject无法实现接口

如何使用Rascal Evaluator从编译的JAR访问Rascal函数?

PhantomReference无法访问时会发生什么?

java.lang.ClassCastException:com.google.firebase.FirebaseException无法转换为com.google.fire base.auth.FirebaseAuthException

使用原子整数的共享计数器并发增量

Cucumber中第二个网页的类对象未初始化

带有提取器的JavaFXObservableList会根据侦听器的存在而改变行为