VÝVOJ PODNIKOVÝCH APLIKACÍ NA PLATFORMĚ JAVA - PŘEDNÁŠKA Zbyněk Šlajchrt http://java.vse.cz/4it447/HomePage Část 7.
Vazby mezi entitami Podobně jako mezi tabulkami v relačních databázích, tak i mezi entitami v JPA mohou být definovány vazby – relace. Příklady Klient a jeho adresa Klient a jeho účty Učet a transakce Výpis z účtu
Typy vazeb One-to-one jednosměrná One-to-one obousměrná Vztah mezi klientem a jeho adresou One-to-one obousměrná Vztah mezi klientem a jeho poštovní schránkou One-to-many jednosměrná Vztah mezi poštovní schránkou a došlými zprávami One-to-many obousměrná Vztah mezi osobním bankéřem a klienty
Typy vazeb Many-to-one jednosměrná Many-to-many jednosměrná Vztah mezi transakcemi a účtem Many-to-many jednosměrná Vztah mezi výpisem a účty Many-to-many obousměrná Vztah mezi klientem a skupinami klientů (např. rodinní příslušníci)
One-to-one jednosměrná Příklad: vztah mezi klientem a jeho adresou Klient má jednu adresu (pro jednoduchost) Na jedné adrese může bydlet pouze jeden klient (pro jednoduchost) Klient má odkaz na adresu Adresa nemá odkaz na klienta
One-to-one jednosměrná Class diagram Entity-relationship diagram
One-to-one jednosměrná Programovací model v JPA Entita, která odkazuje na druhou entitu definuje vlastnost pro uchování odkazu (+ setter a getter) Odkazovaná entita není touto vazbou dotčena Vlastnost je anotována @OneToOne atribut cascade určuje kaskádovou politiky při CRUD operacích nad odkazující entitou Doprovodná anotace @JoinColumn určuje sloupec v tabulce odkazující entity, který udržuje primární klíč odkazované entity (foreign-key)
One-to-one jednosměrná
One-to-one obousměrná Např. vztah mezi klientem a jeho poštovní schránkou Klient udržuje odkaz na svoji poštovní schránku Poštovní schránka udržuje odkaz na klienta u poštovní schránky má asi větší smysl udržovat odkaz na majitele (klienta) než z adresy na obyvatele (klienta)
One-to-one obousměrná
One-to-one obousměrná Programovací model v JPA Obě entity definují vlastnost pro uchování odkazu na protější entitu (+ getter a setter) Vlastnosti jsou anotovány @OneToOne atribut fetch určuje okamžik, kdy se protější entita nahraje LAZY – až v okamžiku první přístupu k odkazované entitě EAGER – při nahrání odkazující entity Lze použít doprovodnou anotaci @JoinColumn Jedna strana vazby je vždy vlastník vazby Druhá strana musí anotace @OneToOne zadat atribut mappedBy – určuje vlastnost protější entity, která ukazuje na tuto entitu.
Problém obousměrných vazeb V případě obousměrných vazeb se rozlišuje vlastnická strana vztahu (owning side) udržuje perzistentní informaci o vazbě opačná strana vztahu (inverse side) neudržuje perzistentně informaci o vazbě odkazuje se na vlastnost se zpětným odkazem u vlastníka vazby atribut mappedBy v @OneToOne nebo @OneMany název vlastnosti protější entity – vlastníka vazby – ukazující zpět na opačnou stranu vazby - @OneToOne(mappedBy="mailBox") Držet se pravidla: nastavit odkazy na obou stranách vazby!
One-to-one obousměrná Vzájemné propojení:
One-to-many jednosměrná Např. vztah mezi poštovní schránkou a došlými zprávami Poštovní schránka udržuje kolekci zpráv, které došly klientovi atribut entity s kolekcí je obvykle typu java.util.List, kde generický parametr je odkazovaná entita - zpráva Zpráva v kolekci neudržuje odkaz na schránku - zbytečné
One-to-many jednosměrná Zpětný ukazatel do tabulky MAILBOX
One-to-many jednosměrná Programovací model v JPA Entita, která odkazuje na více entit, definuje vlastnost typu Collection, List, Set nebo Map (java.util) Prvkem kolekce je odkazovaná entita Vlastnost je anotovaná @OneToMany lze uvést atributy cascade, fetch a orphanRemoval (JPA 2) orphanRemoval – Odstranění entity z kolekce povede k jejímu úplnému odstranění Doprovodná anotace @JoinColumn vlastnosti odkazující entity (1) určuje sloupec na tabulce odkazované entity (N), který ukazuje zpět na odkazující entity – tzv. zpětný ukazatel (jedna z možných implementací)
One-to-many jednosměrná Odstranění odkazu na zprávu z kolekce způsobí odstranění zprávy samotné.
One-to-many obousměrná Např.: vztah mezi osobním bankéřem a klienty Osobní bankéř má na starosti skupinu klientů Klient má přiřazeného právě jednoho osobního bankéře Entita bankéře udržuje kolekci odkazů na klienty Entita klienta udržuje odkaz na bankéře Totožné s obousměrnou vazbou many-to-one věc perspektivy
One-to-many obousměrná
One-to-many obousměrná Programovací model v JPA Entita, která odkazuje na více entit, definuje vlastnost typu Collection, List, Set nebo Map (java.util) Prvkem kolekce je odkazovaná entita Vlastnost je anotovaná @OneToMany atribut mappedBy – určuje vlastnost na protější entitě se zpětným ukazatelem Entita z kolekce definuje vlastnost, která udržuje odkaz na protější entitu. Je vždy vlastníkem vztahu! Vlastnost je anotována @ManyToOne @JoinColumn určuje sloupec pro mapování ukazatele I zde platí: vždy je třeba propojit obě strany vazby!
One-to-many obousměrná Vzájemné propojení:
Many-to-one jednosměrná Např.: vztah mezi transakcemi a účtem Transakce mají odkaz na účet, nad kterým byly provedeny Účet sám na transakce nevidí má trvanlivější charakter než transakce Transakce udržuje vlastnost ukazující na účet Účtu se tato vazba netýká
Many-to-one jednosměrná
Many-to-one jednosměrná Programovací model v JPA Odkazující entita (many) definuje vlastnost ukazující na cílovou entitu (one) Vlastnost je anotována @ManyToOne lze nastavit atributy fetch, cascade Lze použít @JoinColumn pro konfiguraci mapování ukazatele na sloupec v tabulce entity
Many-to-one jednosměrná Získání seznamu transakcí nad vybraným účtem:
Many-to-many jednosměrná Např. vztah mezi výpisy a účty Výpis se může vztahovat k několika účtům Účet může figurovat na více výpisech Účet není touto vazbou nikterak dotčen nevidí na výpisy Výpis definuje vlastnost udržující seznam účtů, pro které je sestaven
Many-to-many jednosměrná
Many-to-many jednosměrná Programovací model v JPA Odkazující entita definuje vlastnost, která udržuje kolekci odkazů na protějšky Vlastnost je anotovaná @ManyToMany Doprovodná mapovací anotace @JoinTable definuje mapování pomocí vazební tabulky name – název vazební tabulky joinColumns – sloupec (sloupce) s PK odkazující entity inverseJoinColumns – sloupec (sloupce) s PK odkazované entity Protější entity se tato vazba přímo netýká
Many-to-many jednosměrná
Many-to-many obousměrná Např.: vztah mezi klientem a skupinami klientů (např. rodinní příslušníci) Klient může patřit do více skupin Skupina obsahuje 0-N klientů Klient vidí na seznam skupin, ve kterých je členem Entita skupiny udržuje seznam svých členů
Many-to-many obousměrná
Many-to-many obousměrná Programovací model v JPA Obě entity definují vlastnost udržující kolekci protějších entit Vlastnost je anotovaná @ManyToMany Lze použít doprovodnou mapovací anotaci @JoinTable Jedna strana musí uvést v anotaci @ManyToMany atribut mappedBy Protějšek této entity se pak stává vlastníkem vazby Znovu je třeba držet se pravidla, že úpravy vazby se provádí na obou stranách
Many-to-many obousměrná Vzájemné propojení:
Použití mapy jako kolekci vazeb java.util.Map lze také použít jako kolekci pro udržování vazeb mezi entitami Klíč v mapě je mapován na vlastnost odkazované entity Anotace @MapKey(name=<vlastnost>) specifikuje vlastnost entity, která se použije jako klíč pokud se neuvede, klíčem se rozumí PK entity
Použití mapy jako kolekci vazeb
Seřazení kolekce vazeb Při sestavování kolekce z databáze lze určit, zda a jak má být výsledná kolekce setříděna Anotace @OrderBy definuje seznam vlastností, podle kterých bude kolekce setříděna Název vlastnosti lze doplnit příznakem asc nebo desc, který určuje, zda se bude podle uvedené vlastnosti setřídit vzestupně či sestupně
Perzistentní seřazení Od verze JPA 2 lze deklarovat, že seřazení entit v kolekci má být perzistentní Pozn.: @OrderBy ovlivňuje dotaz do databáze v okamžiku sestavování kolekce Informace o seřazení kolekce je uchovávána ve speciálním sloupci v tabulce odkazující entity Anotace @OrderColumn slouží ke specifikování tohoto sloupce
Perzistentní seřazení
Perzistentní seřazení
Odpojené entity a vazby V případě, že je entita odpojená, tj. není v kontextu perzistence, může nastat, že některé vlastnosti nebudou nastaveny Týká se vlastností, které mají příznak FetchType.LAZY Platí to i pro vazby Specifikace neříká, jak se má implementace zachovat při přístupu k nenastavené vlastnosti Obvykle se to řeší vyhazováním specifické výjimky Nahrát LAZY vlastnost entity lze Zavoláním getter metody vlastnosti Použitím JPQL operace FETCH JOIN (v další přednášce)
Kaskádová pravidla Operace manažera entit manipulující s entitou se mohou týkat i asociovaných entit Pomocí kaskádových pravidel lze určit vazby, po kterých se budou vyjmenované operace šířit k dalším entitám Anotace @(One|Many)To(One|Many) mají atribut cascade Určuje, jaké operace se budou šířit po vazbě k cílové entitě Hodnota z výčtového typu CascadeType
CascadeType PERSIST MERGE REMOVE REFRESH ALL Pokud vytvářená entita odkazuje na jinou, která ještě nebyla vytvořena, bude také vytvořena. MERGE Pokud připojovaná entita odkazuje na jinou entitu, bude také připojena. Nově asociované entity budou vytvořeny. REMOVE Pokud odstraňovaná entita odkazuje na jinou, bude také odstraněna REFRESH Propaguje obnovení stavu entity na asociované entity ALL