有什么区别:

@Entity
public class Company {

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

and

@Entity
public class Company {

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

当前回答

我只是想补充一下,@JoinColumn并不总是像这个答案所暗示的那样与物理信息位置相关。即使父表中没有指向子表的表数据,也可以将@JoinColumn与@OneToMany组合在一起。

如何在JPA中定义单向的OneToMany关系

单向多对多,无反向多对一,无连接表

它似乎只在JPA 2中可用。尽管x +。当您希望子类只包含父类的ID,而不是完整的on引用时,这是非常有用的。

其他回答

注释@JoinColumn表示该实体是关系的所有者(也就是说:对应的表有一个指向引用表的外键的列),而属性mappedBy表示这一侧的实体是关系的逆,所有者位于“另一个”实体中。这也意味着您可以从用“mappedBy”注释的类中访问另一个表(完全双向关系)。

特别是,对于问题中的代码,正确的注释应该是这样的:

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

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

@JoinColumn可以在关系的双方使用。问题是关于在@OneToMany端使用@JoinColumn(罕见情况)。这里的重点是物理信息复制(列名)以及未优化的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() {
    ...
} 

部队通过部队属性与士兵产生双向多的关系。您不必(一定不)在mappedBy端中定义任何物理映射。

要将一个双向的1映射到多,将一对多的端映射为所属端,您必须删除mappedBy元素,并将多对一的@JoinColumn设置为可插入的,并将可更新的设置为false。此解决方案未经过优化,将产生一些额外的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() {
    ...
}

mappedBy注释理想情况下应该总是在双向关系的父端(Company类)中使用,在这种情况下,它应该在Company类中指向子类(分支类)的成员变量' Company '

注释@JoinColumn用于指定加入实体关联的映射列,这个注释可以在任何类(父类或子类)中使用,但理想情况下,它应该只用于一方(无论是在父类或在子类中,而不是在两者中)在这种情况下,我在双向关系的子方面(分支类)中使用它,指示分支类中的外键。

下面是工作示例:

母公司,公司

@Entity
public class Company {


    private int companyId;
    private String companyName;
    private List<Branch> branches;

    @Id
    @GeneratedValue
    @Column(name="COMPANY_ID")
    public int getCompanyId() {
        return companyId;
    }

    public void setCompanyId(int companyId) {
        this.companyId = companyId;
    }

    @Column(name="COMPANY_NAME")
    public String getCompanyName() {
        return companyName;
    }

    public void setCompanyName(String companyName) {
        this.companyName = companyName;
    }

    @OneToMany(fetch=FetchType.LAZY,cascade=CascadeType.ALL,mappedBy="company")
    public List<Branch> getBranches() {
        return branches;
    }

    public void setBranches(List<Branch> branches) {
        this.branches = branches;
    }


}

子类,分支

@Entity
public class Branch {

    private int branchId;
    private String branchName;
    private Company company;

    @Id
    @GeneratedValue
    @Column(name="BRANCH_ID")
    public int getBranchId() {
        return branchId;
    }

    public void setBranchId(int branchId) {
        this.branchId = branchId;
    }

    @Column(name="BRANCH_NAME")
    public String getBranchName() {
        return branchName;
    }

    public void setBranchName(String branchName) {
        this.branchName = branchName;
    }

    @ManyToOne(fetch=FetchType.LAZY)
    @JoinColumn(name="COMPANY_ID")
    public Company getCompany() {
        return company;
    }

    public void setCompany(Company company) {
        this.company = company;
    }


}

我只是想补充一下,@JoinColumn并不总是像这个答案所暗示的那样与物理信息位置相关。即使父表中没有指向子表的表数据,也可以将@JoinColumn与@OneToMany组合在一起。

如何在JPA中定义单向的OneToMany关系

单向多对多,无反向多对一,无连接表

它似乎只在JPA 2中可用。尽管x +。当您希望子类只包含父类的ID,而不是完整的on引用时,这是非常有用的。

@Entity
public class Company {
  
 @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
 @JoinColumn(name = "company_id_ref", referencedColumnName = "company_id")
 private List<Branch> branches;
  ...
}

这将给出下面的Hibernate日志

Hibernate: select nextval ('hibernate_sequence')
Hibernate: select nextval ('hibernate_sequence')
Hibernate: insert into company (name, company_id) values (?, ?)
Hibernate: insert into branch (company_id_ref, name, id) values (?, ?, ?)
Hibernate: update branch set company_id_ref=? where id=?

And

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

这将给出下面的Hibernate日志

Hibernate: select nextval ('hibernate_sequence')
Hibernate: select nextval ('hibernate_sequence')
Hibernate: insert into company (name, company_id) values (?, ?)
Hibernate: insert into branch (company_id_ref, name, id) values (?, ?, ?)

我们可以清楚地看到@joinColumn将导致额外的更新查询。 所以你不需要显式地将父实体设置为子实体, 这是我们在使用mappedBy时要做的 拯救有父母陪伴的孩子