Jedan na jedan odnos u JPA

1. Uvod

U ovom uputstvu ćemo pogledati različite načine stvaranja pojedinačnih preslikavanja u JPA.

Trebat će nam osnovno razumijevanje okvira za hibernaciju, pa potražite dodatnu pozadinu u našem Vodiču za hibernaciju 5 s proljećem.

2. Opis

Pretpostavimo da gradimo sustav za upravljanje korisnicima, a naš šef traži da spremimo poštansku adresu za svakog korisnika. Korisnik će imati jednu poštansku adresu, a na poštanskoj će adresi biti vezan samo jedan korisnik.

Ovo je primjer odnosa jedan-na-jedan, u ovom slučaju između korisnik i adresa entiteta.

Pogledajmo kako to možemo primijeniti u sljedećim odjeljcima.

3. Korištenje stranog ključa

3.1. Modeliranje stranim ključem

Pogledajmo sljedeći ER dijagram koji predstavlja mapiranje pojedinačno na temelju stranog ključa:

U ovom primjeru, adresa_id stupac u korisnika je strani ključ za adresa.

3.2. Provedba s inozemnim ključem u JPA

Prvo, kreirajmo Korisnik klase i prikladno ga zabilježite:

@Entity @Table (name = "users") korisnik javne klase {@Id @GeneratedValue (strategy = GenerationType.AUTO) @Column (name = "id") private Long id; // ... @OneToOne (cascade = CascadeType.ALL) @JoinColumn (name = "address_id", referencedColumnName = "id") adresa privatne adrese; // ... geteri i postavljači} 

Imajte na umu da postavljamo @Jedan na jedan bilješka na polju povezanog entiteta, Adresa.

Također, moramo postaviti @JoinColumn bilješka za konfiguriranje imena stupca u korisnika tablica koja se preslikava na primarni ključ u adresa stol. Ako ne navedemo ime, tada će Hibernate slijediti neka pravila za odabir zadanog.

Na kraju, imajte na umu u sljedećem entitetu da nećemo koristiti @JoinColumn bilješka tamo. To je zato što nam treba samo na posjedovanje strana odnosa s inozemnim ključem. Jednostavno rečeno, tko god posjeduje stupac stranog ključa dobiva @JoinColumn bilješka.

The Adresa entitet ispada malo jednostavniji:

@Entity @Table (name = "address") Adresa javne klase {@Id @GeneratedValue (strategy = GenerationType.AUTO) @Column (name = "id") private Long id; // ... @OneToOne (mappedBy = "address") privatni korisnik; // ... geteri i postavljači}

Također moramo postaviti @Jedan na jedan bilješka i ovdje. To je zato što je ovo dvosmjeran odnos. Adresna strana odnosa naziva se ne-posjedovanje strana.

4. Korištenje zajedničkog primarnog ključa

4.1. Modeliranje zajedničkim primarnim ključem

U ovoj strategiji, umjesto stvaranja novog stupca adresa_id, označit ćemo primarni ključstupac (user_id) od adresna tablica kao strani ključ za korisnika stol:

Optimizirali smo prostor za pohranu koristeći se činjenicom da ti entiteti imaju međusobni odnos.

4.2. Implementacija zajedničkim primarnim ključem u JPA

Primijetite da se naše definicije samo malo mijenjaju:

@Entity @Table (name = "users") korisnik javne klase {@Id @GeneratedValue (strategy = GenerationType.AUTO) @Column (name = "id") private Long id; // ... @OneToOne (mappedBy = "user", cascade = CascadeType.ALL) Adresa privatne adrese @PrimaryKeyJoinColumn; // ... geteri i postavljači}
@Entity @Table (name = "address") adresa javne klase {@Id @Column (name = "user_id") private Long id; // ... @OneToOne @MapsId @JoinColumn (name = "user_id") privatni korisnik; // ... geteri i postavljači} 

The mapiranBy atribut je sada premješten u Korisnik klase jer je strani ključ sada prisutan u adresa stol. Također smo dodali the @PrimaryKeyJoinColumn napomena koja označava da je primarni ključ Korisnik entitet koristi se kao vrijednost stranog ključa za pridruženo Adresa entitet.

Moramo još definirati @Iskaznica polje u Adresa razreda, ali imajte na umu da se ovo odnosi na user_id stupac i više ne koristi @GeneratedValue bilješka. Također, na polju koje upućuje na Korisnik, dodali smo the @MapsId napomena koja označava da će se vrijednosti primarnog ključa kopirati od Korisnik entitet.

5. Korištenje tablice za spajanje

Mape pojedinačno mogu biti dvije vrste - Neobvezno i Obavezno. Do sada smo vidjeli samo obvezne veze.

Ajmo sada zamisliti da se naši zaposlenici povežu s radnom stanicom. To je jedan na jedan, ali ponekad zaposlenik možda nema radnu stanicu i obrnuto.

5.1. Modeliranje pomoću stola za spajanje

Strategije o kojima smo razgovarali do sada nas prisiljavaju da u stupac stavimo null vrijednosti za obradu neobaveznih odnosa.

Tipično razmišljamo o odnosima mnogo-prema-mnogo kad razmotrimo tablicu pridruživanja, ali, pomoću tablice pridruživanja, u ovom slučaju, može nam pomoći da eliminiramo ove null vrijednosti:

Sad, kad god imamo vezu, napravit ćemo unos u emp_workstation tablicu i izbjegavajte nuleuopće.

5.2. Implementacija s pridruženim stolom u JPA

Naš prvi korišteni primjer @JoinColumn. Ovaj put ćemo upotrijebiti @JoinTable:

@Entity @Table (name = "zaposlenik") zaposlenik javne klase {@Id @GeneratedValue (strategy = GenerationType.AUTO) @Column (name = "id") private Long id; // ... @OneToOne (cascade = CascadeType.ALL) @JoinTable (name = "emp_workstation", joinColumns = {@JoinColumn (name = "worker_id", referencedColumnName = "id")}, inverseJoinColumns = {@JoinColumn (name = "workstation_id", referencedColumnName = "id")}) private WorkStation workStation; // ... geteri i postavljači}
@Entity @Table (name = "radna stanica") Public class WorkStation {@Id @GeneratedValue (strategy = GenerationType.AUTO) @Column (name = "id") private Long id; // ... @OneToOne (mappedBy = "workStation") zaposlenik zaposlenika; // ... geteri i postavljači}

@JoinTable upućuje Hibernate da primijeni strategiju pridruživanja stolu, a da istovremeno održi vezu.

Također, Zaposlenik je vlasnik ovog odnosa jer smo na njemu odlučili upotrijebiti oznaku tablice pridruživanja.

6. Zaključak

U ovom smo tutorijalu naučili različite načine održavanja individualne povezanosti u JPA i Hibernate te kada ih koristiti.

Izvorni kod ovog vodiča možete pronaći na GitHubu.