En-til-en-forhold i JPA

1. Introduksjon

I denne opplæringen vil vi se på forskjellige måter å lage en-til-en-tilordninger i JPA.

Vi trenger en grunnleggende forståelse av Hibernate-rammeverket, så sjekk ut vår guide til Hibernate 5 med Spring for ekstra bakgrunn.

2. Beskrivelse

La oss anta at vi bygger et brukerstyringssystem, og sjefen vår ber oss om å lagre en postadresse for hver bruker. En bruker vil ha en postadresse, og en postadresse vil bare ha en bruker knyttet til den.

Dette er et eksempel på et en-til-en forhold, i dette tilfellet mellom bruker og adresse enheter.

La oss se hvordan vi kan implementere dette i de påfølgende delene.

3. Bruke en utenlandsk nøkkel

3.1. Modellering med en utenlandsk nøkkel

La oss ta en titt på følgende ER-diagram som representerer en fremmed nøkkelbasert en-til-en-kartlegging:

I dette eksemplet er adresse_id kolonne i brukere er den utenlandske nøkkelen til adresse.

3.2. Implementering med en utenlandsk nøkkel i JPA

La oss først lage Bruker klasse og kommentere det på riktig måte:

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

Noter det vi plasserer @OneToOne kommentar på det relaterte enhetsfeltet, Adresse.

Også, vi trenger å plassere @JoinColumn kommentar for å konfigurere navnet på kolonnen i brukere tabell som tilordnes til hovednøkkelen i adresse bord. Hvis vi ikke oppgir noe navn, vil dvalemodus følge noen regler for å velge en standard.

Merk til slutt i neste enhet at vi ikke vil bruke @JoinColumn kommentar der. Dette er fordi vi bare trenger det på eie side av det utenlandske nøkkelforholdet. Enkelt sagt, hvem som helst eier den utenlandske nøkkelkolonnen får @JoinColumn kommentar.

De Adresse enhet viser seg å være litt enklere:

@Entity @Table (name = "address") public class Address {@Id @GeneratedValue (strategy = GenerationType.AUTO) @Column (name = "id") private Lang id; // ... @OneToOne (mappedBy = "adresse") privat brukerbruker; // ... getters og setters}

Vi må også plassere @OneToOne kommentar her også. Det er fordi dette er et toveis forhold. Adressesiden av forholdet kalles ikke-eier side.

4. Bruke en delt primærnøkkel

4.1. Modellering med en delt primærnøkkel

I denne strategien, i stedet for å opprette en ny kolonne adresse_id, Vi markerer hovednøkkelenkolonne (bruker-ID) av adressetabell som den utenlandske nøkkelen til brukere bord:

Vi har optimalisert lagringsplassen ved å benytte det faktum at disse enhetene har et en-til-en forhold mellom seg.

4.2. Implementering med en delt primærnøkkel i JPA

Legg merke til at definisjonene våre endres bare litt:

@Entity @Table (name = "brukere") offentlig klasse bruker {@Id @GeneratedValue (strategi = GenerationType.AUTO) @Column (name = "id") privat Lang id; // ... @OneToOne (mappedBy = "bruker", 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 brukerbruker; // ... getters og setters} 

De kartlagt av attributt flyttes nå til Bruker klasse siden den utenlandske nøkkelen nå er til stede i adresse bord. Vi har også lagt til de @PrimaryKeyJoinColumn merknad, som indikerer at hovednøkkelen til Bruker enhet brukes som den utenlandske nøkkelverdien for den tilknyttede Adresse enhet.

Vi må fremdeles definere en @Id felt i Adresse klasse, men merk deg at dette refererer til bruker-ID kolonnen, og den bruker ikke lenger @GeneratedValue kommentar. Også på feltet som refererer til Bruker, har vi lagt til de @MapsId kommentar, som indikerer at de primære nøkkelverdiene blir kopiert fra Bruker enhet.

5. Bruke et sammenføyningstabell

En-til-en-tilordninger kan være av to typer - Valgfri og Påbudt, bindende. Så langt har vi bare sett obligatoriske forhold.

La oss nå se for oss at våre ansatte blir tilknyttet en arbeidsstasjon. Det er en-til-en, men noen ganger har en ansatt kanskje ikke en arbeidsstasjon og omvendt.

5.1. Modellering med et sammenføyningsbord

Strategiene vi har diskutert til nå tvinge oss til å sette nullverdier i kolonnen for å håndtere valgfrie forhold.

Vanligvis tenker vi på mange-til-mange-forhold når vi vurderer et sammenføyningstabell, men ved å bruke en sammenføyningstabell, i dette tilfellet, kan det hjelpe oss å eliminere disse nullverdiene:

Nå, når vi har et forhold, vil vi gjøre en oppføring i emp_workstation bord og unngå nullhelt.

5.2. Implementering med et Join Table i JPA

Vårt første eksempel brukt @JoinColumn. Denne gangen bruker vi @JoinTable:

@Entity @Table (name = "ansatte") offentlig klasse Ansatt {@Id @GeneratedValue (strategi = GenerationType.AUTO) @Column (name = "id") privat Lang id; // ... @OneToOne (cascade = CascadeType.ALL) @JoinTable (name = "emp_workstation", joinColumn = {@JoinColumn (name = "ansatte_id", referertColumnName = "id")}, inverseJoinColumn = {@JoinColumn (navn = "workstation_id", referertColumnName = "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 ansatt ansatt; // ... getters og setters}

@Bli med på bordet instruerer dvalemodus om å benytte strategien for å delta i bordet mens du opprettholder forholdet.

Også, Ansatt er eieren av dette forholdet da vi valgte å bruke merket om å bli med på tabellen.

6. Konklusjon

I denne opplæringen lærte vi forskjellige måter å opprettholde en en-til-en-forening i JPA og Hibernate, og når vi skulle bruke hver.

Kildekoden til denne veiledningen finner du på GitHub.


$config[zx-auto] not found$config[zx-overlay] not found