Se stiamo lavorando su qualsiasi applicazione hibernate o abbiamo intenzione di lavorare su qualsiasi in futuro, allora si può facilmente capire le relazioni one-to-one tra diverse entità nell’applicazione. In questo esempio di hibernate one to one mapping, discuteremo 4 diverse varianti.
Table of ContentsVarious supported techniques for one to one mapping1. Using foreign key association2. Using join table3. Using shared primary key4. @MapsId
Per questo esempio di hibernate one to one mapping, sto estendendo l’esempio scritto per hibernate hello world. Qui abbiamo due entità: Employee
e Account
.
Un dipendente può avere solo un conto. Allo stesso modo, un conto sarà associato a un solo dipendente. E’ una relazione uno a uno per questo esempio.
Tecniche diverse supportate
In hibernate ci sono 3 modi per creare relazioni uno a uno tra due entità. In entrambi i casi dobbiamo usare l’annotazione @OneToOne.
- La prima tecnica è la più usata e usa una colonna foreign key in una delle tabelle.
- La seconda tecnica usa una soluzione piuttosto nota di avere una terza tabella per memorizzare la mappatura tra le prime due tabelle.
- La terza tecnica è qualcosa di nuovo che usa un valore di chiave primaria comune in entrambe le tabelle.
Hibernate one to one mapping con associazione di chiave esterna
In questo tipo di associazione, viene creata una colonna chiave esterna nell’entità proprietaria. Per esempio, se rendiamo EmployeeEntity proprietaria, allora una colonna extra "ACCOUNT_ID"
sarà creata nella tabella Employee
. Questa colonna memorizzerà la chiave esterna per la tabella Account
.
La struttura della tabella sarà come questa:
Per fare questa associazione, fai riferimento all’entità Account
nella classe EmployeeEntity
come segue:
@OneToOne@JoinColumn(name="ACCOUNT_ID")private AccountEntity account;
La colonna join è dichiarata con l’annotazione @JoinColumn che sembra l’annotazione @Column. Ha un altro parametro chiamato referencedColumnName
. Questo parametro dichiara la colonna nell’entità di destinazione che sarà usata per l’unione.
Se non viene dichiarato nessun @JoinColumn
dal lato del proprietario, si applicano i valori predefiniti. Una colonna di associazione sarà creata nella tabella del proprietario e il suo nome sarà la concatenazione del nome della relazione nel lato del proprietario, _ (underscore), e il nome della colonna della chiave primaria nel lato del proprietario.
In una relazione bidirezionale, uno dei lati (e solo uno) deve essere il proprietario. Il proprietario è responsabile dell’aggiornamento delle colonne dell’associazione. Per dichiarare un lato come non responsabile della relazione, si usa l’attributo mappedBy. ‘mappedBy’ si riferisce al nome della proprietà dell’associazione sul lato proprietario.
@OneToOne(mappedBy="account")private EmployeeEntity employee;
L’attributo “sopra "mappedBy
” dichiara che dipende dall’entità proprietario per la mappatura.
Testiamo le mappature sopra nel codice in esecuzione:
L’esecuzione del codice sopra crea lo schema desiderato nel database ed esegue queste query SQL.
Si possono verificare i dati e le mappature in entrambe le tabelle quando si esegue il programma di cui sopra.
Hibernate one to one mapping con common join table
Questo approccio non è nuovo per tutti noi. Iniziamo con la struttura DB mirata in questa tecnica.
In questa tecnica, l’annotazione principale da usare è @JoinTable. Questa annotazione è usata per definire il nuovo nome della tabella (obbligatorio) e le chiavi esterne di entrambe le tabelle. Vediamo come si usa:
L’annotazione @JoinTable è usata nella classe EmployeeEntity
. Dichiara che una nuova tabella EMPLOYEE_ACCOUNT
sarà creata con due colonne EMPLOYEE_ID
(chiave primaria della tabella EMPLOYEE) e ACCOUNT_ID
(chiave primaria della tabella ACCOUNT).
Il test di queste entità genera le seguenti query SQL nei file di log:
Hibernate one to one mapping con chiave primaria condivisa
In questa tecnica, hibernate si assicura di usare un valore di chiave primaria comune in entrambe le tabelle. In questo modo la chiave primaria di EmployeeEntity
può essere tranquillamente assunta come chiave primaria anche di AccountEntity
.
La struttura della tabella sarà come questa:
In questo approccio, @PrimaryKeyJoinColumn è la principale annotazione da usare. Vediamo come usarla.
@OneToOne(cascade = CascadeType.ALL)@PrimaryKeyJoinColumnprivate AccountEntity account;
In AccountEntity
lato, rimarrà dipendente dall’entità proprietaria per la mappatura.
@OneToOne(mappedBy="account", cascade=CascadeType.ALL)private EmployeeEntity employee;
Provare le entità di cui sopra genera le seguenti query SQL nei file di log:
Hibernate one to one mapping con @MapsId
In questa tecnica, hibernate assume che sia la fonte che la destinazione condividano gli stessi valori di chiave primaria.
In questo approccio, @MapsId è l’annotazione principale da usare. Vediamo come usarla.
@Idprivate Integer employeeId;@OneToOne @MapsIdprivate AccountEntity account;
Nel lato AccountEntity
, rimarrà dipendente dall’entità proprietaria per la mappatura.
@Idprivate Integer accountId;
Testare le entità di cui sopra genera le seguenti query SQL nei file di log: