使用@OneToMany和@ManyToMany之间的区别

时间:2011-11-19 11:18:44

标签: java java-ee jpa

我在理解@OneToMany@ManyToMany之间的区别时遇到了一些麻烦。当我使用@OneToMany时,它默认创建一个JoinTable,如果添加mappedBy属性,则两个实体之间将具有双向关系。

我的Question可能属于许多Categories,而Category可能属于许多Questions。我不明白我是否应该使用@ManyToMany@OneToMany因为对我而言似乎完全相同,但可能不是。

有人可以解释一下吗?

3 个答案:

答案 0 :(得分:18)

嗯,不同之处在于您尝试使用对象进行反映的设计。

在您的情况下,每个Question都可以分配给多个Categories - 这是@*ToMany关系的标志。现在你必须决定:

  • 每个Category只能分配一个Question(这将导致唯一约束,这意味着没有其他类别可以引用相同的问题) - 这将是@OneToMany关系,
  • 每个Category可以分配多个QuestionsCategory表中没有唯一约束) - 这将是@ManyToMany关系。

@OneToMany(问题 - >类别)

只有当您使用@JoinTable或使用单向关系明确定义时,此关系才能通过连接表来表示,其中拥有方是“一方”(它)表示在Question实体中您拥有Categories的集合,但在Categories中您没有对Question的任何引用。

如果你考虑一下,使用连接表似乎是合理的。没有其他方法DBMS可以在Question表中的一行与Categories表中的多行之间保存连接。

但是,如果您想建模双向关系,则需要指定Category('多'侧)是关系的拥有方。在这种情况下,DBMS可以在Category表中创建带有外键的连接列,因为每个Category行只能与一个Question连接。

通过这种方式,您没有任何连接表,只有简单的外键(仍然如开头所指,您可以强制使用@JoinTable创建连接表。)

<强> @ManyToMany

此关系必须表示为连接表。它基本上与单向@OneToMany关系非常相似,但在这种情况下,您可能有多个来自Question的行与来自Categories的多行相连接。

答案 1 :(得分:1)

@ManyToMany关系在关系的两边都有相互引用的外键。有时,这种关系是由相邻的表调解的。

@OneToMany关系在“一”侧有一个外键,而在“很多”侧没有外键。在@OneToMany关系中,一个对象是“父”,一个是“子”。父母控制孩子的存在。

请记住@ManyToMany双向关系不一定是对称的!

答案 2 :(得分:0)

在你的问题与解答中分类情况下,你应该使用@ManyToMany关系。 @ManyToMany基本上意味着“一个问题可以同时属于许多类别”和“一个类别可以同时包含许多问题”。将自动创建一个新表来存储映射。你的代码看起来像这样:

@Entity
public class Question implements Serializable {
    ...
    @ManyToMany
    private List<Category> categories;
    ...
}

@Entity
public class Category implements Serializable {
    ...
    @ManyToMany
    private List<Question> questions;
    ...
}

如果您对问题和类别使用@OneToMany关系(让我们说一方面的类别和另一方面的问题),这意味着“一个问题只能属于一个类别”和“一个类别可以包含很多问题同时”。不需要新表来存储映射。相反,将在Many侧自动创建一个新字段以记录One侧的ID。你的代码看起来像这样:

@Entity
public class Question implements Serializable {
    ...
    @ManyToOne
    private Category theCategory;
    ...
}

@Entity
public class Category implements Serializable {
    ...
    @OneToMany(mappedBy="theCategory")
    private List<Question> questions;
    ...
}