What's the difference between @JoinColumn and mappedBy when using a JPA @OneToMany association
之间有什么区别?
1 2 3 4 5 6 7 8 | @Entity public class Company { @OneToMany(cascade = CascadeType.ALL , fetch = FetchType.LAZY) @JoinColumn(name ="companyIdRef", referencedColumnName ="companyId") private List<Branch> branches; ... } |
和
1 2 3 4 5 6 7 | @Entity public class Company { @OneToMany(cascade = CascadeType.ALL , fetch = FetchType.LAZY, mappedBy ="companyIdRef") private List<Branch> branches; ... } |
注释
特别是,对于问题中的代码,正确的注释应如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 |
根据文档:
由于JPA规范中的一对多关系(几乎)始终是双向关系的所有者,因此,@ OneToMany(mappedBy = ...)注释了一对多关联。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
部队通过部队属性与士兵建立了双向的一对多关系。您不必(不必)在mapledBy端定义任何物理映射。
要以一对多方为拥有方映射双向一对多,您必须删除mapledBy元素,并将多对一设置为@JoinColumn,以将其可插入,并将其可更新为false。此解决方案未经过优化,将产生一些其他的UPDATE语句。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
正如我在本文中所解释的,如果将
如果将
单向
您最好使用效率更高的双向
理想情况下,始终应在双向关系的父级(公司类)中使用mapledBy注释,在这种情况下,注释应在公司类中指向子类(分支类)的成员变量" company"
注释@JoinColumn用于指定用于连接实体关联的映射列,该注释可以在任何类(父类或子类)中使用,但理想情况下应仅在一侧使用(在父类或子类中不使用)在这两种情况下,在这种情况下,我在双向关系的子级(分支类)中使用了它,指示了分支类中的外键。
以下是工作示例:
家长班
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | @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; } } |
子班,分支
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | @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; } } |
我想补充一下,
如何在JPA中定义单向OneToMany关系
单向OneToMany,Noverse ManyToOne,无联接表
不过,它似乎仅在
我不同意óscarLópez在这里所接受的答案。这个答案不正确!
不是
诸如
@JoinColumn
The purpose of
@JoinColumn is to create a join column if one does
not already exist. If it does, then this annotation can be used to
name the join column.
映射
The purpose of the
MappedBy parameter is to instruct JPA: Do NOT
create another join table as the relationship is already being mapped
by the opposite entity of this relationship.
请记住:
之所以说不使用
因此,总而言之:
为了说明
因此,我们使用
1 2 3 4 5 6 7 8 9 10 11 |
在所有者类中添加@JoinColumn(name =" driverID")(请参见下文)将阻止创建联接表,而是在Cars表中创建driverID外键列以构建映射:
1 2 3 4 5 6 7 8 9 10 11 12 |
JPA是一个分层的API,不同级别具有各自的注释。最高级别是(1)描述持久性类的Entity级别,然后您具有(2)关系数据库级别,其中假定实体已映射到关系数据库,以及(3)Java模型。
1级注释:@ Entity,@ Id,@ OneToOne,@ OneToMany,@ ManyToOne,@ ManyToMany。
您可以仅使用这些高级注释在应用程序中引入持久性。但是随后您必须根据JPA所做的假设来创建数据库。这些注释指定实体/关系模型。
2级注释:@ Table,@ Column,@ JoinColumn,...
如果您对JPA的默认设置不满意或需要映射到现有数据库,请影响从实体/属性到关系数据库表/列的映射。这些注释可视为实现注释,它们指定应如何完成映射。
在我看来,最好尽可能地坚持高级注释,然后根据需要引入低级注释。
回答问题:@ OneToMany / mappedBy最好,因为它仅使用来自实体域的注释。 @ oneToMany / @ JoinColumn也很好,但是在并非严格必要的地方使用了实现注释。