有什么区别:

@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表示该实体是关系的所有者(也就是说:对应的表有一个指向引用表的外键的列),而属性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表示该实体是关系的所有者(也就是说:对应的表有一个指向引用表的外键的列),而属性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() {
    ...
}

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

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

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

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

单向一对多关联

如果你使用@OneToMany注释和@JoinColumn,那么你就有一个单向的关联,就像下图中父Post实体和子PostComment之间的关联一样:

当使用单向一对多关联时,只有父端映射该关联。

在这个例子中,只有Post实体定义了与子PostComment实体的@OneToMany关联:

@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
@JoinColumn(name = "post_id")
private List<PostComment> comments = new ArrayList<>();

双向一对多关联

如果您使用带有mappedBy属性集的@OneToMany,那么您就有了一个双向关联。在我们的例子中,Post实体都有一个PostComment子实体的集合,并且子PostComment实体有一个指向父Post实体的引用,如下图所示:

在PostComment实体中,post实体属性映射如下:

@ManyToOne(fetch = FetchType.LAZY)
private Post post;

我们显式地将fetch属性设置为FetchType的原因。LAZY是因为默认情况下,所有的@ManyToOne和@OneToOne关联都是急切获取的,这可能会导致N+1个查询问题。

在Post实体中,评论关联映射如下:

@OneToMany(
    mappedBy = "post",
    cascade = CascadeType.ALL,
    orphanRemoval = true
)
private List<PostComment> comments = new ArrayList<>();

@OneToMany注释的mappedBy属性引用子PostComment实体中的post属性,通过这种方式,Hibernate知道双向关联是由@ManyToOne控制的,它负责管理这个表关系所基于的外键列值。

对于双向关联,你还需要有两个实用工具方法,比如addChild和removecchild:

public void addComment(PostComment comment) {
    comments.add(comment);
    comment.setPost(this);
}

public void removeComment(PostComment comment) {
    comments.remove(comment);
    comment.setPost(null);
}

这两种方法确保双向关联的双方是同步的。如果两端不同步,Hibernate不能保证关联状态更改会传播到数据库。

选择哪一个?

单向的@OneToMany关联性能不太好,所以应该避免使用它。

您最好使用更有效的双向@OneToMany。

让我简单说一下。 不管映射如何,您都可以在任意一侧使用@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”映射在分支表中,得到我所有分支的列表。注意:在这种情况下你不能从分支获取公司,从公司到分支只存在单向映射。