474 votes

JPA JoinColumn vs mappedBy

Quelle est la différence entre:

@Entity
public class Company {

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

et

@Entity
public class Company {

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

516voto

Óscar López Points 97105

L'annotation @JoinColumn indique que cette entité est le propriétaire de la relation (ce qui est: le correspondant de la table a une colonne de clé étrangère pour la table référencée), tandis que l'attribut mappedBy indique que l'entité dans ce côté est l'inverse de la relation, et le propriétaire réside dans "l'autre" de l'entité.

En particulier, pour le code de la question de la bonne annotations devraient ressembler à ceci:

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

207voto

Mykhaylo Adamovych Points 1907

Selon la documentation:

Depuis de nombreuses à un sont (presque) toujours le propriétaire de côté d'une relation bidirectionnelle dans la JPA spec, l'un à de nombreuses association est annotée par @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() {
    ...
} 

La troupe a bidirectionnelle "un à plusieurs" de la relation avec un Soldat par la troupe de la propriété. Vous n'avez pas à (ne doit pas) définir physique de la cartographie dans les mappedBy côté.

Pour mapper un bidirectionnel, un à plusieurs, avec l' un-à-plusieurs côté que le propriétaire de côté, vous devez supprimer le mappedBy élément et réglez le nombre de un les annotations @JoinColumn comme insérable et pouvant être mis à jour à false. Cette solution n'est pas optimisé et produisent une certaine supplémentaire de mise à JOUR des déclarations.

@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() {
    ...
}

32voto

Soumyaansh Points 99

L'annotation mappedBy , idéalement, devrait toujours être utilisé dans le Parent du côté de l'Entreprise (classe) de la bi directionnelle de la relation, dans ce cas, il devrait être dans la Société de classe, pointant à la variable de membre de "l'entreprise" de l'Enfant de la classe (Direction générale de la classe)

L'annotation @JoinColumn est utilisé pour spécifier une colonne mappés pour rejoindre une entité association, cette annotation peut être utilisée dans n'importe quelle classe (Parent ou Enfant), mais idéalement, il devrait être utilisé que dans un seul côté (soit dans la classe parent ou de l'Enfant de la classe pas dans les deux), ici, dans ce cas, je l'ai utilisé chez l'Enfant de côté (Direction générale de la classe) de la bi relation directionnelle indiquant la clé étrangère dans la Direction de la classe.

ci-dessous l'exemple de travail :

classe parent , Société

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


}

enfant de la classe, de la Direction générale

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


}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by: