Quelle est la différence entre les annotations @JoinColumn et mappedBy lors de l'utilisation d'une JPA @OneToMany association
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;
...
}
- Voir aussi qu'est-Ce que le propriétaire de côté dans un ORM mapping question pour une très bonne explication des enjeux.
Vous devez vous connecter pour publier un commentaire.
L'annotation
@JoinColumn
indique que cette entité est la 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'attributmappedBy
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é. Cela signifie également que vous pouvez accéder à l'autre de la table à partir de la classe dont vous avez annoté par "mappedBy" (entièrement relation bidirectionnelle).En particulier, pour le code de la question de la bonne annotations devraient ressembler à ceci:
@JoinColumn
dansCompany
Branch
n'a pas une propriété dont les référencesCompany
, mais la table sous-jacente a une colonne qui n', alors vous pouvez utiliser@JoinTable
de la carte. C'est une situation inhabituelle, parce que vous le feriez normalement la carte de la colonne de l'objet qui correspond à sa table, mais il peut arriver, et c'est parfaitement légitime.NonProfitCompany
serait nécessaire dans la classeBranch
@OneToOne
, l'enfant de lignes mis à jour avec unnull
dans leur FKey colonne qui fait référence à la société mère.private Long companyId;
alors je doit indiquer@ManyToOne(targetEntity = Company.class)
et la@JoinColumn
restera le même ?@JoinColumn
pourrait être utilisé sur les deux côtés de la relation. La question était de savoir à l'aide de@JoinColumn
sur le@OneToMany
côté (cas rare). Et le point ici est dans physique dédoublement de l'information (nom de la colonne) avec pas optimisé requête SQL qui produisent une certaine mise à JOUR supplémentaire états.Selon la documentation:
Depuis beaucoup à 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=...)
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é.
À la carte bidirectionnelle un à plusieurs, avec la 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 mise à JOUR supplémentaire consolidés.
mappedBy="troop"
reportez-vous à la rubrique?mappedBy="troop"
fait référence à la propriété de la troupe dans la classe de Soldat. Dans le code ci-dessus, la propriété n'est pas visible car ici Mykhaylo omis, mais vous pouvez déduire de son existence, par la lecture getTroop(). Vérifiez la réponse de Oscar López, il est très clair et vous obtenez le point.Comme je l'ai expliqué dans cet article, si vous utilisez le
@OneToMany
annotation avec@JoinColumn
, alors vous avez une association unidirectionnelle.Si vous utilisez le
@OneToMany
avec lemappedBy
ensemble d'attributs, vous disposez d'une association bidirectionnelle, ce qui signifie que vous devez avoir un@ManyToOne
association sur le côté qui lemappedBy
références.La unidirectionnel
@OneToMany
association n'a pas d'effectuer très bien, de sorte que vous devriez éviter.Vous êtes mieux d'utiliser le bidirectionnelle
@OneToMany
qui est plus efficace.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 membre "société" de l'Enfant de la classe (Direction générale de la classe)
L'annotation les annotations@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 est le travail exemple :
classe parent , Société
enfant de la classe, de la Direction générale
Je voudrais juste ajouter que
@JoinColumn
ne sont pas toujours liées à la physique de l'information de localisation comme cette réponse suggère. Vous pouvez combiner@JoinColumn
avec@OneToMany
même si la table parent n'a pas de table de données pointant vers la table enfant.Comment définir unidirectionnel relation OneToMany en JPA
Unidirectionnel OneToMany, Aucune Inverse ManyToOne, Pas De Table De Jointure
Elle semble être la seule à être disponible en
JPA 2.x+
bien. C'est utile pour les situations où vous voulez que votre enfant de la classe juste à contenir l'IDENTIFIANT de la mère, pas un de référence.Je suis en désaccord avec la accepté de répondre ici par Oscar López. La réponse est inexacte!
Il n'est PAS
@JoinColumn
qui indique que cette entité est le propriétaire de la relation. Au lieu de cela, c'est la@ManyToOne
annotation qui le fait (dans son exemple).La relation des annotations telles que
@ManyToOne
,@OneToMany
et@ManyToMany
dire JPA/Hibernate pour créer un mappage. Par défaut, cela se fait à travers une autre Table de Jointure.Les annotations@JoinColumn
MappedBy
Rappelez-vous:
MappedBy
est une propriété de la relation annotations dont le but est de générer un mécanisme permettant de lier deux entités qui, par défaut, ils le font par la création d'une table de jointure.MappedBy
s'arrête que le processus dans un seul sens.L'entité n'utilisant pas
MappedBy
est dit être le propriétaire de la relation, car la mécanique de la cartographie sont dictées à l'intérieur de sa catégorie grâce à l'utilisation de l'un des trois cartographie des annotations contre le champ de clé étrangère. Ce n'est pas seulement spécifie la nature de la cartographie mais indique également à la création d'une table de jointure. En outre, l'option pour supprimer la jointure de la table existe aussi en appliquant les annotations @JoinColumn annotation sur la clé étrangère qui la maintient à l'intérieur de la table de l'entité propriétaire à la place.Donc en résumé:
@JoinColumn
crée une nouvelle colonne de jointure ou renomme un existant; tandis que laMappedBy
paramètre travaille en collaboration avec la relation des annotations de l'autre (l'enfant) de la classe afin de créer un mappage soit par le biais d'une table de jointure ou par la création d'une colonne de clé étrangère dans la table associée de la propriétaire de l'entité.Pour illustrer comment
MapppedBy
œuvres, considérez le code ci-dessous. SiMappedBy
paramètre devaient être supprimés, Hibernate serait en fait de créer DEUX tables de jointure! Pourquoi? Car il y a une symétrie dans plusieurs-à-plusieurs liens et mise en veille prolongée n'a pas de justification pour la sélection d'une direction sur l'autre.Nous utilisons donc la
MappedBy
dire Hibernate, nous avons choisi l'autre entité de dicter la cartographie de la relation entre les deux entités.L'ajout d'annotations @JoinColumn(name = "driverID") dans le propriétaire de la classe (voir ci-dessous), permettra d'éviter la création d'une table de jointure et au lieu de cela, créer un driverID colonne de clé étrangère dans la table de Voitures à construire une cartographie:
JPA est une couche d'API, les différents niveaux ont leurs propres annotations. Le niveau le plus élevé est le (1) au niveau de l'Entité qui décrit les classes persistantes, alors vous avez la (2) de bases de données relationnelles niveau qui assument les entités sont mappés à une base de données relationnelle et (3) la java du modèle.
Niveau 1 annotations: @Entity, @Id @OneToOne, @OneToMany, @ManyToOne, @ManyToMany.
Vous pouvez introduire la persistance dans votre application à l'aide de ces annotations seul. Mais ensuite, vous devez créer votre base de données selon les hypothèses JPA fait. Ces annotations spécifier l'entité/relation modèle.
Niveau 2 annotations: @Table @Colonne, les annotations @JoinColumn, ...
Influence de la cartographie à partir d'entités/propriétés de la base de données relationnelle tables/colonnes si vous n'êtes pas satisfait avec JPA par défaut ou si vous avez besoin d'une carte à une base de données existante. Ces annotations peuvent être vu comme la mise en œuvre annotions, ils spécifient la façon dont la correspondance doit être fait.
À mon avis, il est préférable de s'en tenir autant que possible le niveau élevé des annotations et ensuite introduire le niveau inférieur des annotations en tant que de besoin.
Pour répondre aux questions: le @OneToMany/mappedBy est plus beau car il utilise uniquement les annotations de l'entité de domaine. Le @oneToMany/@JoinColumn est aussi bien, mais il utilise une mise en œuvre d'annotation lorsque cela n'est pas strictement nécessaire.