En-til-en-relation i JPA

1. Introduktion

I denne vejledning ser vi på forskellige måder at oprette en-til-en-kortlægning i JPA på.

Vi har brug for en grundlæggende forståelse af dvale-rammen, så tjek vores guide til dvale 5 med foråret for ekstra baggrund.

2. Beskrivelse

Lad os antage, at vi bygger et User Management System, og vores chef beder os om at gemme en postadresse til hver bruger. En bruger vil have en postadresse, og en postadresse vil kun have en bruger bundet til den.

Dette er et eksempel på et en-til-et forhold, i dette tilfælde mellem bruger og adresse enheder.

Lad os se, hvordan vi kan implementere dette i de efterfølgende afsnit.

3. Brug af en fremmed nøgle

3.1. Modellering med en fremmed nøgle

Lad os se på følgende ER-diagram, der repræsenterer en fremmed nøglebaseret en-til-en-kortlægning:

I dette eksempel er adresse_id kolonne i brugere er den udenlandske nøgle til adresse.

3.2. Implementering med en udenlandsk nøgle i JPA

Lad os først oprette Bruger klasse og kommentere det passende:

@Entity @Table (name = "brugere") offentlig klasse bruger {@Id @GeneratedValue (strategi = GenerationType.AUTO) @Column (name = "id") privat Lang id; // ... @OneToOne (cascade = CascadeType.ALL) @JoinColumn (name = "address_id", refereretColumnName = "id") privat adresse adresse; // ... getters og setters} 

Noter det vi placerer @En til en kommentar på det relaterede enhedsfelt Adresse.

Også, vi er nødt til at placere @JoinColumn kommentar for at konfigurere kolonnens navn i brugere tabel, der kortlægges til den primære nøgle i adresse bord. Hvis vi ikke giver et navn, vil dvale følge nogle regler for at vælge en standard.

Endelig skal du bemærke i den næste enhed, at vi ikke bruger @JoinColumn kommentar der. Dette er fordi vi kun har brug for det på ejer side af det udenlandske nøgleforhold. Kort sagt, hvem som helst ejer kolonnen udenlandsk nøgle får @JoinColumn kommentar.

Det Adresse enhed viser sig at være lidt enklere:

@Entity @Table (navn = "adresse") offentlig klasse Adresse {@Id @GeneratedValue (strategi = GenerationType.AUTO) @Column (navn = "id") privat Lang id; // ... @OneToOne (mappedBy = "adresse") privat brugerbruger; // ... getters og setters}

Vi er også nødt til at placere @En til en kommentar her også. Det er fordi dette er et tovejsforhold. Adressesiden af ​​forholdet kaldes ikke-ejer side.

4. Brug af en delt primær nøgle

4.1. Modellering med en delt primær nøgle

I stedet for at oprette en ny kolonne i denne strategi adresse_id, vi markerer den primære nøglekolonne (bruger ID) af adressetabel som den fremmede nøgle til brugere bord:

Vi har optimeret lagerpladsen ved at udnytte det faktum, at disse enheder har et en-til-en-forhold mellem dem.

4.2. Implementering med en delt primær nøgle i JPA

Bemærk, at vores definitioner kun ændres lidt:

@Entity @Table (name = "brugere") offentlig klasse bruger {@Id @GeneratedValue (strategi = GenerationType.AUTO) @Column (name = "id") privat Lang id; // ... @OneToOne (mappedBy = "bruger", cascade = CascadeType.ALL) @PrimaryKeyJoinColumn privat adresse adresse; // ... getters og setters}
@Entity @Table (name = "address") public class Address {@Id @Column (name = "user_id") private Lang id; // ... @OneToOne @MapsId @JoinColumn (name = "user_id") privat brugerbruger; // ... getters og setters} 

Det kortlagt af attribut flyttes nu til Bruger klasse, da den fremmede nøgle nu er til stede i adresse bord. Vi har også tilføjet det @PrimaryKeyJoinColumn kommentar, hvilket indikerer, at den primære nøgle til Bruger enhed bruges som den udenlandske nøgleværdi for den tilknyttede Adresse enhed.

Vi er stadig nødt til at definere en @Id felt i Adresse klasse, men bemærk dette refererer til bruger ID kolonne, og den bruger ikke længere @GeneratedValue kommentar. Også på det felt, der refererer til Bruger, har vi tilføjet det @MapsId kommentar, som indikerer, at de primære nøgleværdier kopieres fra Bruger enhed.

5. Brug af en sammenføjningstabel

En-til-en-kortlægning kan være af to typer - Valgfri og Obligatorisk. Indtil videre har vi kun set obligatoriske forhold.

Lad os nu forestille os, at vores medarbejdere bliver tilknyttet en arbejdsstation. Det er en-til-en, men nogle gange har en medarbejder muligvis ikke en arbejdsstation og omvendt.

5.1. Modellering med et sammenføjningsbord

De strategier, vi har diskuteret indtil nu tvinge os til at sætte nulværdier i kolonnen for at håndtere valgfri relationer.

Vi tænker typisk på mange-til-mange-forhold, når vi overvejer en sammenføjningstabel, men ved hjælp af en sammenføjningstabel kan det i dette tilfælde hjælpe os med at fjerne disse nulværdier:

Nu, når vi har et forhold, foretager vi en post i emp_workstation tabel og undgå nulhelt.

5.2. Implementering med en Join Table i JPA

Vores første eksempel brugt @JoinColumn. Denne gang bruger vi @JoinTable:

@Entity @Table (name = "medarbejder") offentlig klasse Medarbejder {@Id @GeneratedValue (strategi = GenerationType.AUTO) @Column (name = "id") privat Lang id; // ... @OneToOne (cascade = CascadeType.ALL) @JoinTable (name = "emp_workstation", joinColumns = {@JoinColumn (name = "employee_id", referencedColumnName = "id")}, inverseJoinColumn = {@JoinColumn (name = "workstation_id", refereretColumnName = "id")}) privat WorkStation workStation; // ... getters og setters}
@Entity @Table (name = "workstation") offentlig klasse WorkStation {@Id @GeneratedValue (strategi = GenerationType.AUTO) @Column (name = "id") privat Lang id; // ... @OneToOne (mappedBy = "workStation") privat medarbejdermedarbejder; // ... getters og setters}

@Deltag i bordet instruerer dvale om at anvende strategien for at deltage i bordet, samtidig med at forholdet opretholdes.

Også, Medarbejder er ejeren af ​​dette forhold, da vi valgte at bruge sammenføjningstabelkommentaren på det.

6. Konklusion

I denne vejledning lærte vi forskellige måder at opretholde en en-til-en-forening i JPA og Hibernate, og hvornår de skulle bruges.

Kildekoden til denne vejledning kan findes på GitHub.