JPA JoinColumn vs mappedBy

来源:互联网 发布:手工客软件 编辑:程序博客网 时间:2024/06/05 19:43

What is the difference between:

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

and

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

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.

In particular, for the code in the question the correct annotations would look like this:

@Entitypublic class Company {    @OneToMany(fetch = FetchType.LAZY, mappedBy = "company")    private List<Branch> branches;}
@Entitypublic class Branch {    @ManyToOne(fetch = FetchType.LAZY)    @JoinColumn(name = "companyId")    private Company company;}

@JoinColumn could be used on both sides of the relationship. The question was about using @JoinColumn on the @OneToMany side (rare case). And the point here is in physical information location.

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=...)

@Entitypublic class Troop {    @OneToMany(mappedBy="troop")    public Set<Soldier> getSoldiers() {    ...}
@Entitypublic 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.

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. This solution is not optimized and will produce some additional UPDATE statements.

@Entitypublic class Troop {    @OneToMany    @JoinColumn(name="troop_fk") //we need to duplicate the physical information    public Set<Soldier> getSoldiers() {    ...}
@Entitypublic class Soldier {    @ManyToOne    @JoinColumn(name="troop_fk", insertable=false, updatable=false)    public Troop getTroop() {    ...}
0 0