Egyszemélyes kapcsolat a JPA-ban
1. Bemutatkozás
Ebben az oktatóanyagban megvizsgáljuk az egy az egyhez való hozzárendelések létrehozásának különböző módjait a JPA-ban.
Szükségünk lesz a Hibernate keretrendszer alapvető ismeretére, ezért kérjük, olvassa el a Hibernálás 5 tavasszal című útmutatónkat az extra háttérképért.
2. Leírás
Tegyük fel, hogy felhasználói kezelő rendszert építünk, és főnökünk arra kér minket, hogy minden felhasználó számára tároljunk egy levelezési címet. A felhasználónak egyetlen levelezési címe lesz, és egy levelezési címhez csak egy felhasználó lesz kötve.
Ez egy példa az egy-egy kapcsolatra, ebben az esetben a kettőre felhasználó és cím entitások.
Nézzük meg, hogyan tudjuk ezt megvalósítani a következő szakaszokban.
3. Idegen kulcs használata
3.1. Modellezés idegen kulccsal
Vessünk egy pillantást a következő ER diagramra, amely egy idegen kulcs alapú egy az egyhez hozzárendelést ábrázol:

Ebben a példában a address_id oszlop felhasználók az idegen kulcsa cím.
3.2. Végrehajtás külföldi kulccsal a JPA-ban
Először hozzuk létre a Felhasználó osztály és megfelelő jegyzetekkel ellátva:
@Entity @Table (name = "users") public class User {@Id @GeneratedValue (strategy = GenerationType.AUTO) @Column (name = "id") private Long id; // ... @OneToOne (cascade = CascadeType.ALL) @JoinColumn (név = "cím_azonosító", hivatkozottColumnName = "id") privát címcím; // ... getterek és beállítók}
Vegye figyelembe, hogy elhelyezzük a @1-1 annotáció a kapcsolódó entitás mezőben, Cím.
Is, el kell helyeznünk a @JoinColumn annotáció az oszlop nevének konfigurálásához a felhasználók táblázat, amely leképezi az elsődleges kulcsot a cím asztal. Ha nem adunk meg nevet, akkor a hibernálás néhány szabályt követve kiválaszt egy alapértelmezettet.
Végül vegye figyelembe a következő entitásban, hogy nem fogjuk használni a @JoinColumn annotáció ott. Ez azért van, mert csak a birtoklása a külföldi kulcskapcsolat oldala. Egyszerűen fogalmazva, bárki birtokolja az idegen kulcs oszlop megkapja a @JoinColumn annotáció.
A Cím az entitás kissé egyszerűbb:
@Entity @Table (name = "address") public class Cím {@Id @GeneratedValue (strategy = GenerationType.AUTO) @Column (name = "id") private Long id; // ... @OneToOne (mappedBy = "address") privát Felhasználó felhasználó; // ... getterek és beállítók}
Helyeznünk kell a @1-1 annotáció itt is. Ez azért van, mert ez kétirányú kapcsolat. A kapcsolat címoldalát hívjuk nem tulajdonos oldal.
4. Megosztott elsődleges kulcs használata
4.1. Modellezés megosztott elsődleges kulccsal
Ebben a stratégiában egy új oszlop létrehozása helyett address_id, meg fogjuk jelölni az elsődleges kulcsotoszlop (Felhasználói azonosító) a címtábla mint a külföldi kulcs a felhasználók asztal:

Optimalizáltuk a tárhelyet, kihasználva azt a tényt, hogy ezek az entitások egymással szemben állnak.
4.2. Megvalósítás megosztott elsődleges kulccsal a JPA-ban
Vegye figyelembe, hogy meghatározásaink csak kis mértékben változnak:
@Entity @Table (name = "users") public class User {@Id @GeneratedValue (strategy = GenerationType.AUTO) @Column (name = "id") private Long id; // ... @OneToOne (mappedBy = "user", cascade = CascadeType.ALL) @PrimaryKeyJoinColumn privát cím címe; // ... getterek és beállítók}
@Entity @Table (name = "address") public class Address {@Id @Column (name = "user_id") private Long id; // ... @OneToOne @MapsId @JoinColumn (name = "user_id") privát Felhasználó felhasználó; // ... getterek és beállítók}
A feltérképezve attribútum átkerült a Felhasználó osztály, mivel az idegen kulcs már jelen van a cím asztal. Mi is hozzáfűztük a @PrimaryKeyJoinColumn megjegyzés, amely azt jelzi, hogy a Felhasználó entitást használják a társított külföldi kulcsértékeként Cím entitás.
Még meg kell határoznunk egy @Id mező a Cím osztály, de vegye figyelembe, hogy ez hivatkozik a Felhasználói azonosító oszlopot, és már nem használja a @GeneratedValue annotáció. Továbbá azon a területen, amely hivatkozik a Felhasználó, hozzáadtuk a @MapsId annotáció, amely azt jelzi, hogy az elsődleges kulcs értékei át lesznek másolva tól Felhasználó entitás.
5. Összekötő táblázat használata
Az egy az egyhez hozzárendelés kétféle lehet - Választható és Kötelező. Eddig csak kötelező kapcsolatokat láttunk.
Lássuk csak, képzeljük el, hogy munkatársaink egy munkaállomáshoz kapcsolódnak. Ez egy az egyben, de néha előfordulhat, hogy az alkalmazottnak nincs munkaállomása és fordítva.
5.1. Modellezés egy asztallal
A megbeszélt stratégiák eddig arra kényszerített minket, hogy az opcionális kapcsolatok kezelése érdekében null értékeket tegyünk az oszlopba.
Általában sok-sok kapcsolatra gondolunk, ha egy csatlakozási táblázatot veszünk figyelembe, de ebben az esetben egy csatlakozási tábla használata segíthet nekünk a nullértékek kiküszöbölésében:

Most, amikor kapcsolatunk van, beírjuk a emp_workstation táblázatot, és kerülje a nullákatteljesen.
5.2. Végrehajtás csatlakozási táblával a JPA-ban
Első példánk @JoinColumn. Ezúttal használjuk @JoinTable:
@Entity @Table (név = "alkalmazott") public class Employee {@Id @GeneratedValue (strategy = GenerationType.AUTO) @Column (name = "id") private Long id; // ... @OneToOne (cascade = CascadeType.ALL) @JoinTable (név = "emp_workstation", joinColumns = {@JoinColumn (név = "alkalmazott_id", hivatkozottColumnName = "id")}, inverseJoinColumns = {@JoinColumn (név = "workstation_id", referiatedColumnName = "id")}) private WorkStation workStation; // ... getterek és beállítók}
@Entity @Table (name = "workstation") public class WorkStation {@Id @GeneratedValue (strategy = GenerationType.AUTO) @Column (name = "id") private Long id; // ... @OneToOne (mappedBy = "workStation") magán alkalmazott alkalmazott; // ... getterek és beállítók}
@JoinTable utasítja a Hibernate-et, hogy a kapcsolat fenntartása mellett alkalmazza a csatlakozási asztal stratégiát.
Is, Munkavállaló ennek a kapcsolatnak a tulajdonosa, mivel úgy döntöttünk, hogy a csatlakozási tábla feljegyzését használjuk rajta.
6. Következtetés
Ebben az oktatóanyagban megtanultuk, hogyan lehet egy-egy társulást fenntartani a JPA-ban és a Hibernátumban, és mikor kell használni ezeket.
Az oktatóanyag forráskódja megtalálható a GitHub oldalon.