Pokud pracujeme na nějaké aplikaci hibernate nebo se chystáme na nějaké v budoucnu pracovat, pak snadno pochopíte vztahy one-to-one mezi několika entitami v aplikaci. V tomto příkladu mapování hibernate one to one probereme 4 různé varianty.
Table of ContentsVarious supported techniques for one to one mapping1. Using foreign key association2. Using join table3. Using shared primary key4. @MapsId
Pro tento příklad mapování hibernate one to one rozšiřuji příklad napsaný pro příklad hibernate hello world. Máme zde dvě entity: Employee
a Account
.
Jeden zaměstnanec může mít pouze jeden účet. Stejně tak bude účet spojen pouze s jedním zaměstnancem. V tomto příkladu se jedná o vztah jedna ku jedné.
Různé podporované techniky
V systému hibernate existují 3 způsoby, jak vytvořit vztah jedna ku jedné mezi dvěma entitami. Každým z těchto způsobů musíme použít anotaci @OneToOne.
- První technika je nejpoužívanější a používá sloupec cizího klíče v jedné z tabulek.
- Druhá technika používá poměrně známé řešení, kdy máme třetí tabulku pro uložení mapování mezi prvními dvěma tabulkami.
- Třetí technika je něco nového, co používá společnou hodnotu primárního klíče v obou tabulkách.
Hibernate one to one mapping with foreign key association
V tomto druhu asociace je vytvořen sloupec cizího klíče v entitě vlastníka. Pokud například učiníme vlastníkem entitu EmployeeEntity, pak se v tabulce Employee
vytvoří další sloupec "ACCOUNT_ID"
. V tomto sloupci bude uložen cizí klíč pro tabulku Account
.
Struktura tabulky bude vypadat takto:
Pro vytvoření takové asociace se odkazujeme na entitu Account
ve třídě EmployeeEntity
takto:
@OneToOne@JoinColumn(name="ACCOUNT_ID")private AccountEntity account;
Sloupec join se deklaruje pomocí anotace @JoinColumn, která vypadá jako anotace @Column. Má ještě jeden parametr s názvem referencedColumnName
. Tento parametr deklaruje sloupec v cílové entitě, který bude použit ke spojení.
Pokud není na straně vlastníka deklarován @JoinColumn
, platí výchozí hodnoty. V tabulce vlastníka bude vytvořen sloupec(y) pro připojení a jeho název bude tvořen součinem názvu vztahu na straně vlastníka, _ (podtržítko) a názvu sloupce(ů) primárního klíče na straně vlastníka.
V obousměrném vztahu musí být jedna ze stran (a pouze jedna) vlastníkem. Vlastník je odpovědný za aktualizaci sloupce (sloupců) asociace. K prohlášení strany, že není odpovědná za vztah, se používá atribut mappedBy. ‚mappedBy‘ odkazuje na název vlastnosti asociace na straně vlastníka.
@OneToOne(mappedBy="account")private EmployeeEntity employee;
Atribut "mappedBy
“ deklaruje, že je při mapování závislý na entitě vlastníka.
Vyzkoušejme výše uvedené mapování v běžícím kódu:
Výše uvedený kód vytvoří v databázi požadované schéma a spustí tyto SQL dotazy.
Po spuštění výše uvedeného programu si můžete ověřit data a mapování v obou tabulkách.
Mapování jedna ku jedné pomocí společné spojovací tabulky
Tento přístup není pro nás všechny novinkou. Začněme cílenou strukturou DB v této technice.
V této technice se používá hlavně anotace @JoinTable. Tato anotace slouží k definici názvu nové tabulky (povinné) a cizích klíčů z obou tabulek. Podívejme se, jak se používá:
Anotace @JoinTable se používá ve třídě EmployeeEntity
. Deklaruje, že bude vytvořena nová tabulka EMPLOYEE_ACCOUNT
se dvěma sloupci EMPLOYEE_ID
(primární klíč tabulky EMPLOYEE) a ACCOUNT_ID
(primární klíč tabulky ACCOUNT).
Testování výše uvedených entit generuje následující dotazy SQL v souborech protokolu:
Hibernate one to one mapping with shared primary key
Při této technice hibernate zajistí, že v obou tabulkách použije společnou hodnotu primárního klíče. Tímto způsobem lze primární klíč tabulky EmployeeEntity
bezpečně považovat za primární klíč také tabulky AccountEntity
.
Struktura tabulky bude vypadat takto:
V tomto přístupu je hlavní anotací, kterou je třeba použít, @PrimaryKeyJoinColumn. Podívejme se, jak ji použít.
@OneToOne(cascade = CascadeType.ALL)@PrimaryKeyJoinColumnprivate AccountEntity account;
Na straně AccountEntity
zůstane závislost na entitě vlastníka pro mapování.
@OneToOne(mappedBy="account", cascade=CascadeType.ALL)private EmployeeEntity employee;
Testování výše uvedených entit generuje následující dotazy SQL v souborech protokolu:
Hibernate one to one mapping with @MapsId
V této technice hibernate předpokládá, že zdroj i cíl mají stejné hodnoty primárního klíče.
V tomto přístupu je @MapsId hlavní anotací, kterou je třeba použít. Podívejme se, jak ji použít.
@Idprivate Integer employeeId;@OneToOne @MapsIdprivate AccountEntity account;
Na straně AccountEntity
zůstane závislost na entitě vlastníka pro mapování.
@Idprivate Integer accountId;
Při testování výše uvedených entit se v souborech protokolu generují následující dotazy SQL:
.