为什么Hibernate为单向OneToMany创建联接表?

21
为什么 Hibernate 对这些类使用联接表?
@Entity
public class CompanyImpl {
    @OneToMany
    private Set<Flight> flights;


@Entity
public class Flight {

我既不想要连接表,也不想要双向关联 :(

3个回答

22

因为这是它的设计方式,以及JPA规范要求将这样的关联映射。如果想在Flight表中使用连接列,请使用

@Entity
public class CompanyImpl {
    @OneToMany
    @JoinColumn(name = "company_id")
    private Set<Flight> flights;
}

这个已经有文档记录了


5
“因为这就是它的设计原理”对我来说似乎并不是一个理由,而更像是一个事实:P - Alfonso Nishikawa
7
推理是,因为这是单向关联,所以“多”的一方不知道关联的存在,因此其表格不应该有映射该关联的列。 - JB Nizet
4
那其实是一个原因 :) 谢谢。+1 - Alfonso Nishikawa
@jbnizet,我对你在评论区提出的理由不满意。因为如果另一方不知道关联,表就不应该有映射列,你如何证明这一点?因为单向反向是可能的,即多对一。那么你的说法如何成立,即在单向情况下不可能呢? - JAVA
1
我认为原因是在一方表中无法维护多方表的外键,这在逻辑上和实际上都是不可能的,所以他们去创建一个新的连接表。如果我错了,请纠正我。 - JAVA
显示剩余2条评论

5
Hibernate使用关联表来映射关系,而另一张表(即多的一方)并不知道任何表存在。它将创建一个映射器。
文档说明使用@OneToMany和@ManyToMany可以映射相关实体的集合、列表、映射和集合。
如果您没有指定@joincolumn,这是关于您的问题,将使用单向一对多与连接表。表名是所有者表名、_和另一侧表名的串联。引用所有者表的外键名称是所有者表、_和所有者主键列名的串联。
因此,如果您不想使用一对多创建连接表(映射器),则可能需要指定@joinColumn。
@Entity
public class CompanyImpl {
    @OneToMany
     @JoinColumn(name=flights_id)
    private Set<Flight> flights;


@Entity
public class Flight {

2
我认为以上给出的答案不够详细,希望这可以帮助解决问题。
原因:为什么Hibernate会创建联接表。
Hibernate会为单向OneToMany创建Join Table,因为根据实现,外键始终保持在“多”侧。所以在您的示例中,外键将保留在Flight表侧,并因此要防止在Many侧具有null值,Hibernate选择创建JoinTable。
根据您的示例,每个Flight都将有一个CompanyImpl列,如果未设置,则必须为null,因此为了避免在某些Flight记录中出现null值,Hibernate选择使用JoinTable存储Flight和CompanyImpl的Ids。

但是拥有空值有什么害处呢?实际上这是一样的。在这两种实现中,我都会得到该航班的空值。 - chetan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接