一尘不染

使用JPA @OneToMany关联时,@ JoinColumn和mappedBy有什么区别

java

之间有什么区别?

@Entity
public class Company {

    @OneToMany(cascade = CascadeType.ALL , fetch = FetchType.LAZY)
    @JoinColumn(name = "companyIdRef", referencedColumnName = "companyId")
    private List<Branch> branches;
    ...
}

@Entity
public class Company {

    @OneToMany(cascade = CascadeType.ALL , fetch = FetchType.LAZY, mappedBy = "companyIdRef")
    private List<Branch> branches;
    ...
}

阅读 1547

收藏
2020-02-27

共2个答案

一尘不染

@JoinColumn可以在关系的两边使用。现在的问题是关于使用@JoinColumn@OneToMany侧(极少数情况下)。这里的重点是物理信息重复(列名)以及未优化的SQL查询,这会产生一些其他UPDATE语句。

根据文件:

由于多对一的(几乎)总是所有者侧的在JPA规范的双向关系中,一对多关联是通过注解@OneToMany(mappedBy=...)

@Entity
public class Troop {
    @OneToMany(mappedBy="troop")
    public Set<Soldier> getSoldiers() {
    ...
}

@Entity
public class Soldier {
    @ManyToOne
    @JoinColumn(name="troop_fk")
    public Troop getTroop() {
    ...
} 

TroopSoldier通过troop属性具有双向的一对多关系。你不必(不必)在mappedBy侧面定义任何物理映射。

要以一对多方为拥有方映射双向一对多,你必须删除mappedBy元素并将多对数设置@JoinColumnas insertableupdatablefalse。此解决方案未经过优化,将产生一些其他UPDATE语句。

@Entity
public class Troop {
    @OneToMany
    @JoinColumn(name="troop_fk") //we need to duplicate the physical information
    public Set<Soldier> getSoldiers() {
    ...
}

@Entity
public class Soldier {
    @ManyToOne
    @JoinColumn(name="troop_fk", insertable=false, updatable=false)
    public Troop getTroop() {
    ...
}
2020-02-27
一尘不染

批注@JoinColumn指示此实体是关系的所有者(即:对应的表具有一列,该列带有被引用表的外键),而属性mappedBy指示此侧的实体是关系的逆向,并且所有者居住在“其他”实体中。这也意味着您可以从使用“ mappedBy”(完全双向关系)注释的类中访问另一个表。

特别是,对于问题中的代码,正确的注释应如下所示:

@Entity
public class Company {
    @OneToMany(fetch = FetchType.LAZY, mappedBy = "company")
    private List<Branch> branches;
}

@Entity
public class Branch {
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "companyId")
    private Company company;
}
2020-02-27