Dans JPA, il existe un attribut appelé referencedColumnName
qui peut être défini sur @JoinColumn, @PrimaryKeyJoinColumn
quelle est l'idée derrière ce paramètre, quelqu'un peut-il donner un bon exemple d'utilisation de celui-ci?
Il est là pour spécifier une autre colonne comme colonne par défaut id de l’autre table, par exemple. considérer ce qui suit
TableA
id int identity
tableb_key varchar
TableB
id int identity
key varchar unique
// in class for TableA
@JoinColumn(name="tableb_key", referencedColumnName="key")
La propriété "referenceColumnName" est le nom de la colonne de la table à laquelle vous faites référence avec la colonne que vous annotez. Ou de manière brève: c'est la colonne référencée dans la table de destination. Imaginez quelque chose comme ceci: voitures et personnes. Une personne peut avoir plusieurs voitures, mais une voiture n'appartient qu'à une seule personne (désolé, je n'aime personne qui conduit ma voiture).
Table Person
nom car (64) clé primaire
age intVoiture de table
car_registration char (32) clé primaire
car_brand (caractère 64)
modèle_car (char64)
owner_name char (64) références de clé étrangère Nom d'une personne)
Lorsque vous implémentez des classes, vous obtenez quelque chose comme
class Person{
...
}
class Car{
...
@ManyToOne
@JoinColumn(columnName="owner_name", referencedColumnName="name")
private Person owner;
}
J'espère que cela t'aides.
Citant API sur referenceColumnName :
Nom de la colonne référencée par cette colonne de clé étrangère.
Par défaut (s'applique uniquement si une colonne de jointure unique est utilisée): le même nom que la colonne de clé primaire de la table référencée.
Où cela serait utilisé?
Lorsqu'il existe une PK composite dans la table référencée , vous devez spécifier le nom de la colonne à référencer.
name
attribut pointe vers la colonne contenant l'association, c'est-à-dire le nom de la colonne de la clé étrangèrereferencedColumnName
attribut pointe vers la colonne associée dans l'entité associée/référencée, c'est-à-dire le nom de colonne de la clé primaireVous n'êtes pas obligé de remplir le referencedColumnName
si l'entité référencée a une seule colonne comme clé PK, car il ne fait aucun doute que la colonne à laquelle elle fait référence (c'est-à-dire l'ID de colonne Address
unique).
@ManyToOne
@JoinColumn(name="ADDR_ID")
public Address getAddress() { return address; }
Toutefois, si l’entité référencée a une PK qui couvre plusieurs colonnes, l’ordre dans lequel vous spécifiez @JoinColumn
annotations a une signification. Cela pourrait fonctionner sans le referencedColumnName
spécifié, mais c'est par chance. Donc, vous devriez le mapper comme ceci:
@ManyToOne
@JoinColumns({
@JoinColumn(name="ADDR_ID", referencedColumnName="ID"),
@JoinColumn(name="ADDR_Zip", referencedColumnName="Zip")
})
public Address getAddress() { return address; }
ou en cas de ManyToMany
:
@ManyToMany
@JoinTable(
name="CUST_ADDR",
joinColumns=
@JoinColumn(name="CUST_ID"),
inverseJoinColumns={
@JoinColumn(name="ADDR_ID", referencedColumnName="ID"),
@JoinColumn(name="ADDR_Zip", referencedColumnName="Zip")
}
)
Deux requêtes générées par Hibernate du même mappage de table de jointure, toutes deux sans la colonne référencée spécifiée. Seulement l'ordre de @JoinColumn
_ annotations ont été modifiées.
/* load collection Client.emails */
select
emails0_.id_client as id1_18_1_,
emails0_.rev as rev18_1_,
emails0_.id_email as id3_1_,
email1_.id_email as id1_6_0_
from client_email emails0_
inner join email email1_ on emails0_.id_email=email1_.id_email
where emails0_.id_client='2' and
emails0_.rev='18'
/* load collection Client.emails */
select
emails0_.rev as rev18_1_,
emails0_.id_client as id2_18_1_,
emails0_.id_email as id3_1_,
email1_.id_email as id1_6_0_
from client_email emails0_
inner join email email1_ on emails0_.id_email=email1_.id_email
where emails0_.rev='2' and
emails0_.id_client='18'
Nous interrogeons une table de jointure pour obtenir les emails du client. Le {2, 18}
est l'identifiant composite du client. L'ordre des noms de colonne est déterminé par votre ordre de @JoinColumn
annotations. L'ordre des deux entiers est toujours le même, probablement trié par veille prolongée et c'est pourquoi n alignement correct avec les colonnes de la table de jointure est requis et nous ne pouvons pas ou ne devrions pas compter sur l'ordre de mappage.
La chose intéressante est que l'ordre des nombres entiers ne correspond pas à l'ordre dans lequel ils sont mappés dans l'entité - dans ce cas, je m'attendrais à ce que {18, 2}
. Il semble donc qu'Hibernate trie les noms de colonnes avant de les utiliser dans une requête. Si cela est vrai et que vous commanderiez votre @JoinColumn
de la même manière que vous n’auriez pas besoin de referencedColumnName
, mais je ne le dis que pour illustration.
Les attributs referencedColumnName
correctement remplis donnent exactement la même requête sans ambiguïté, dans mon cas la deuxième requête (rev = 2
, id_client = 18
).
Pour un exemple d’utilisation de JPA 2.x dans le cas général de deux tables, avec un @OneToMany
jointure unidirectionnelle voir https://en.wikibooks.org/wiki/Java_Persistence/OneToMany#Example_of_a_JPA_2.x_unidirectional_OneToMany_relationship_annotations
Capture d'écran de cet article de JPA sur WikiBooks: Exemple d'une base de données de relations unidirectionnelles JPA 2.x OneToMany
(Facultatif) Nom de la colonne référencée par cette colonne de clé étrangère.
Exemple:
Dept
Long id;
String deptNo;
String name;
Employee
Long id;
String EmpNo;
String Name;
@JoinColumn(name = "dept", referencedColumnName = "deptNo")
Dept dept;