有什么区别:

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

当前回答

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。

我们把它分成三种情况。 1)分公司到公司的单向映射。 2)公司到分公司的双向映射。 3)从公司到分公司只能单向映射。

因此任何用例都可以归入这三类。让我来解释一下如何使用@JoinColumn和mappedBy。 1)分公司到公司的单向映射。 在Branch表中使用JoinColumn。 2)公司到分公司的双向映射。 使用mappedBy在公司表描述@Mykhaylo Adamovych的回答。 3)公司到分公司的单向映射。 在Company表中使用@JoinColumn即可。

@Entity
public class Company {

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

这就是说,在基于外键“courseId”映射在分支表中,得到我所有分支的列表。注意:在这种情况下你不能从分支获取公司,从公司到分支只存在单向映射。

@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时要做的 拯救有父母陪伴的孩子

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

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

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

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

我不同意Óscar López这里接受的答案。这个答案是不准确的!

它不是@JoinColumn,这表明该实体是关系的所有者。取而代之的是@ManyToOne注释(在他的例子中)。

关系注释如@ManyToOne, @OneToMany和@ManyToMany告诉JPA/Hibernate创建映射。默认情况下,这是通过一个单独的连接表来完成的。

@JoinColumn

@JoinColumn的目的是创建一个连接列(如果有的话) 不存在。如果是,则可以使用此注释 命名连接列。

的MappedBy

MappedBy参数的目的是指示JPA: Do NOT 创建另一个连接表,因为已经映射了关系 通过这种关系的相反实体。

请记住:MappedBy是关系注释的一个属性,其目的是生成一种机制来关联两个实体,默认情况下,它们通过创建一个连接表来实现。MappedBy在一个方向上停止这个过程。

The entity not using MappedBy is said to be the owner of the relationship because the mechanics of the mapping are dictated within its class through the use of one of the three mapping annotations against the foreign key field. This not only specifies the nature of the mapping but also instructs the creation of a join table. Furthermore, the option to suppress the join table also exists by applying @JoinColumn annotation over the foreign key which keeps it inside the table of the owner entity instead.

总的来说:@JoinColumn要么创建一个新的连接列,要么重命名一个现有的连接列;而MappedBy参数与其他(子)类的关系注释协同工作,以便通过连接表或在所有者实体的关联表中创建外键列来创建映射。

为了说明MapppedBy是如何工作的,考虑下面的代码。如果MappedBy参数被删除,那么Hibernate实际上会创建两个连接表!为什么?因为在多对多关系中存在对称性,Hibernate没有理由选择一个方向而不是另一个方向。

因此,我们使用MappedBy告诉Hibernate,我们已经选择了另一个实体来指示两个实体之间关系的映射。

@Entity
public class Driver {
    @ManyToMany(mappedBy = "drivers")
    private List<Cars> cars;
}

@Entity
public class Cars {
    @ManyToMany
    private List<Drivers> drivers;
}

在owner类中添加@JoinColumn(name = "driverID")(见下文),将防止创建连接表,相反,在Cars表中创建一个driverID外键列来构建映射:

@Entity
public class Driver {
    @ManyToMany(mappedBy = "drivers")
    private List<Cars> cars;
}

@Entity
public class Cars {
    @ManyToMany
    @JoinColumn(name = "driverID")
    private List<Drivers> drivers;
}

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


}