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

本文翻译自:What's the difference between @JoinColumn and mappedBy when using a JPA @OneToMany association

What is the difference between: 之间有什么区别?

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

#1楼

参考:https://stackoom.com/question/o5gT/使用JPA-OneToMany关联时-JoinColumn和mappedBy有什么区别


#2楼

The annotation @JoinColumn indicates that this entity is the owner of the relationship (that is: the corresponding table has a column with a foreign key to the referenced table), whereas the attribute mappedBy indicates that the entity in this side is the inverse of the relationship, and the owner resides in the "other" entity. 注释@JoinColumn指示此实体是关系的所有者 (即:对应的表具有一列,该列带有被引用表的外键),而属性mappedBy指示此侧的实体是该关系的逆。关系,并且所有者位于“其他”实体中。 This also means that you can access the other table from the class which you've annotated with "mappedBy" (fully bidirectional relationship). 这也意味着您可以从用“ mappedBy”(完全双向关系)注释的类中访问另一个表。

In particular, for the code in the question the correct annotations would look like this: 特别是,对于问题中的代码,正确的注释应如下所示:

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

#3楼

@JoinColumn could be used on both sides of the relationship. 在关系的两边都可以使用@JoinColumn The question was about using @JoinColumn on the @OneToMany side (rare case). 问题是关于在@OneToMany端使用@JoinColumn (罕见情况)。 And the point here is in physical information duplication (column name) along with not optimized SQL query that will produce some additional UPDATE statements . 这里的要点是物理信息重复 (列名)以及未优化的SQL查询,这会产生一些其他的UPDATE语句

According to documentation : 根据文件

Since many to one are (almost) always the owner side of a bidirectional relationship in the JPA spec, the one to many association is annotated by @OneToMany(mappedBy=...) 由于多对一是 (几乎)总是在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() {
    ...
} 

Troop has a bidirectional one to many relationship with Soldier through the troop property. 部队通过部队属性与士兵建立了双向的一对多关系。 You don't have to (must not) define any physical mapping in the mappedBy side. 您不必(不必)在mapledBy端定义任何物理映射。

To map a bidirectional one to many, with the one-to-many side as the owning side , you have to remove the mappedBy element and set the many to one @JoinColumn as insertable and updatable to false. 以一对多方为拥有方映射双向一对多,您必须删除mapledBy元素,并将多对一设置为@JoinColumn,以将其可插入,并将其可更新为false。 This solution is not optimized and will produce some additional UPDATE statements. 此解决方案未经过优化,将产生一些其他的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() {
    ...
}

#4楼

The annotation mappedBy ideally should always be used in the Parent side (Company class) of the bi directional relationship, in this case it should be in Company class pointing to the member variable 'company' of the Child class (Branch class) 理想情况下,始终应在双向关系的父级(公司类)中使用mapledBy注释,在这种情况下,注释应在公司类中指向子类(分支类)的成员变量“ company”

The annotation @JoinColumn is used to specify a mapped column for joining an entity association, this annotation can be used in any class (Parent or Child) but it should ideally be used only in one side (either in parent class or in Child class not in both) here in this case i used it in the Child side (Branch class) of the bi directional relationship indicating the foreign key in the Branch class. 注释@JoinColumn用于指定用于连接实体关联的映射列,该注释可以在任何类(父类或子类)中使用,但理想情况下仅应在一侧使用(在父类或子类中不使用)在这两种情况下,在这种情况下,我在双向关系的子级(分支类)中使用了它,指示了分支类中的外键。

below is the working example : 以下是工作示例:

parent class , Company 家长班

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


}

child class, Branch 子班,分支

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


}

#5楼

I'd just like to add that @JoinColumn does not always have to be related to the physical information location as this answer suggests. 我只想补充一下, @JoinColumn不一定总是与物理信息位置相关,如答案所示。 You can combine @JoinColumn with @OneToMany even if the parent table has no table data pointing to the child table. 即使父表没有指向子表的表数据,也可以将@JoinColumn@OneToMany组合在一起。

How to define unidirectional OneToMany relationship in JPA 如何在JPA中定义单向OneToMany关系

Unidirectional OneToMany, No Inverse ManyToOne, No Join Table 单向OneToMany,Noverse ManyToOne,无联接表

It seems to only be available in JPA 2.x+ though. 不过,它似乎仅在JPA 2.x+可用。 It's useful for situations where you want the child class to just contain the ID of the parent, not a full on reference. 对于希望子类仅包含父级ID而不是完整引用的情况,这很有用。


#6楼

As I explained in this article , if you use the @OneToMany annotation with @JoinColumn , then you have a unidirectional association. 正如我在本文中所解释的,如果将@OneToMany注释与@JoinColumn一起@JoinColumn ,则您将具有单向关联。

If you use the @OneToMany with the mappedBy attribute set, you have a bidirectional association, meaning you need to have a @ManyToOne association on the child side which the mappedBy references. 如果使用@OneToManymappedBy属性集,你有一个双向关联,这意味着你需要有一个@ManyToOne对孩子一侧的关联mappedBy引用。

The unidirectional @OneToMany association does not perform very well , so you should avoid it. 单向@OneToMany关联的效果不佳 ,因此应避免使用它。

You are better off using the bidirectional @OneToMany which is more efficient . 您最好使用效率更高双向@OneToMany

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值