web-dev-qa-db-fra.com

A quoi sert referenceColumnName dans JPA?

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?

61
ams

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")
60
Firo

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 int

Voiture 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.

38
EAmez

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.

Q/A

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.

20
JMelnik
  • name attribut pointe vers la colonne contenant l'association, c'est-à-dire le nom de la colonne de la clé étrangère
  • referencedColumnName 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é primaire

Vous 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")
    }
)

Exemple de la vie réelle

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

7

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

0
Progster219

(Facultatif) Nom de la colonne référencée par cette colonne de clé étrangère.

  • Lorsqu'elle est utilisée avec des mappages de relations d'entité autres que les cas décrits ici, la colonne référencée se trouve dans la table de l'entité cible.
  • Lorsqu'elle est utilisée avec un mappage de clé étrangère OneToMany unidirectionnel, la colonne référencée se trouve dans la table de l'entité source.
  • Lorsqu'elle est utilisée dans une annotation JoinTable, la colonne de clé référencée se trouve dans la table d'entités de l'entité propriétaire ou dans l'entité inverse si la jointure fait partie de la définition de la jointure inverse.
  • Lorsqu'elle est utilisée dans un mappage CollectionTable, la colonne référencée se trouve dans la table de l'entité contenant la collection.

Exemple:

Dept
   Long id;
   String deptNo;
   String name;

Employee
  Long id;
  String EmpNo;
  String Name;
  @JoinColumn(name = "dept", referencedColumnName = "deptNo")
  Dept dept;
0
Syed Mehtab Hassan