A cosa si riferisce il nome della colonna di riferimento utilizzato in JPA?

In JPA c’è un attributo chiamato referencedColumnName che può essere impostato su @JoinColumn, @PrimaryKeyJoinColumn qual è l’idea alla base di questa impostazione, qualcuno può dare un buon esempio di dove può essere usato?

È lì per specificare un’altra colonna come colonna id predefinita dell’altra tabella, ad esempio considerare quanto segue

 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 proprietà “referencedColumnName” è il nome della colonna nella tabella che stai facendo riferimento alla colonna che stai analizzando. O in un modo breve: è la colonna referenziata nella tabella di destinazione. Immagina qualcosa di simile: auto e persone. Una persona può avere molte macchine, ma una macchina appartiene a una sola persona (mi dispiace, non mi piace nessun altro alla guida della mia auto).

Tabella Persona
nome char (64) chiave primaria
età int

Tavolo Car
car_registration char (32) chiave primaria
car_brand (char 64)
car_model (char64)
owner_name char (64) riferimenti di chiavi esterne Persona (nome)

Quando implementi le lezioni avrai qualcosa di simile

 class Person{ ... } class Car{ ... @ManyToOne @JoinColumn(columnName="owner_name", referencedColumnName="name") private Person owner; } 

Spero che questo ti aiuti.

Citando API su referencedColumnName :

Il nome della colonna a cui fa riferimento questa colonna chiave esterna.

Predefinito (si applica solo se viene utilizzata una singola colonna di join): lo stesso nome della colonna della chiave primaria della tabella di riferimento.

Q / A

Dove sarebbe usato?

Quando nella tabella di riferimento è presente un PK composito , è necessario specificare il nome della colonna a cui si fa riferimento.

  • name attributo name punta alla colonna contenente l’asociation, ovvero il nome della colonna della chiave esterna
  • referencedColumnName attribuisce i punti alla colonna correlata nell’ quadro asociata / referenziata, ovvero il nome della colonna della chiave primaria

Non sei obbligato a riempire il referencedColumnName se l’ quadro referenziata ha una colonna singola come PK, perché non c’è dubbio sulla colonna a cui fa riferimento (cioè l’ID della singola colonna Address ).

 @ManyToOne @JoinColumn(name="ADDR_ID") public Address getAddress() { return address; } 

Tuttavia, se l’entity framework di riferimento ha PK che si estende su più colonne, l’ordine in cui si specificano @JoinColumn annotazioni @JoinColumn ha significato. Potrebbe funzionare senza il referencedColumnName specificato, ma è solo per fortuna. Quindi dovresti mapparlo in questo modo:

 @ManyToOne @JoinColumns({ @JoinColumn(name="ADDR_ID", referencedColumnName="ID"), @JoinColumn(name="ADDR_ZIP", referencedColumnName="ZIP") }) public Address getAddress() { return address; } 

o in caso di ManyToMany :

 @ManyToMany @JoinTable( name="CUST_ADDR", joinColumns= @JoinColumn(name="CUST_ID"), inverseJoinColumns={ @JoinColumn(name="ADDR_ID", referencedColumnName="ID"), @JoinColumn(name="ADDR_ZIP", referencedColumnName="ZIP") } ) 

Esempio di vita reale

Due query generate da Hibernate con la stessa mapping della tabella di join, entrambe senza la colonna di riferimento specificata. Sono state modificate solo le ordinanze delle annotazioni @JoinColumn .

 /* 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' 

Stiamo interrogando una tabella di join per ottenere le email del cliente. Il {2, 18} è l’ID composito del client. L’ordine dei nomi delle colonne è determinato dall’ordine delle annotazioni @JoinColumn . L’ordine di entrambi gli interi è sempre lo stesso, probabilmente ordinato per ibernazione ed è per questo che è richiesto un corretto allineamento con le colonne della tabella di join e non possiamo o dovremmo basarci sull’ordine di mapping.

La cosa interessante è che l’ordine degli interi non corrisponde all’ordine in cui sono mappati nell’ quadro – in tal caso mi aspetterei {18, 2} . Quindi sembra che Hibernate stia ordinando i nomi delle colonne prima di usarli nella query. Se questo è vero e @JoinColumn nello stesso modo in cui non avresti bisogno di referencedColumnName , ma lo dico solo per illustrazione.

Gli attributi referencedColumnName correttamente compilati generano esattamente la stessa query senza l’ambiguità, nel mio caso la seconda query ( rev = 2 , id_client = 18 ).

Per l’utilizzo di esempio di JPA 2.x per il caso generale di due tabelle, con un @OneToMany unidirezionale @OneToMany consultare https://en.wikibooks.org/wiki/Java_Persistence/OneToMany#Example_of_a_JPA_2.x_unidirectional_OneToMany_relationship_annotations

Screenshot da questo articolo JPA WikiBooks: Esempio di un database di relazioni OneToMany unidirezionale JPA 2.x