Objektové štáty v relácii Hibernate

1. Úvod

Hibernate je vhodný rámec na správu trvalých údajov, ale pochopenie toho, ako to funguje interne, môže byť niekedy zložité.

V tomto tutoriále sa dozvieme o stavoch objektov a o tom, ako sa medzi nimi pohybovať. Pozrime sa tiež na problémy, s ktorými sa môžeme stretnúť s odpojenými entitami, a na to, ako ich vyriešiť.

2. Relácia dlhodobého spánku

The Session rozhranie je hlavným nástrojom používaným na komunikáciu s režimom dlhodobého spánku. Poskytuje API, ktoré nám umožňuje vytvárať, čítať, aktualizovať a mazať trvalé objekty. The zasadanie má jednoduchý životný cyklus. Otvoríme ho, vykonáme nejaké operácie a potom ho zavrieme.

Keď operujeme objekty počas zasadanie, pripútajú sa k tomu zasadanie. Zmeny, ktoré vykonáme, sa zistia a uložia po uzavretí. Po zatvorení režim dlhodobého spánku preruší spojenia medzi objektmi a reláciou.

3. Objektové štáty

V kontexte režimu dlhodobého spánku Session, objekty môžu byť v jednom z troch možných stavov: prechodný, pretrvávajúci alebo odpojený.

3.1. Prechodné

Objekt, ktorý sme k žiadnemu nepripojili zasadanie je v prechodnom stave. Pretože nikdy nepretrvával, nemá v databáze žiadne zastúpenie. Pretože nie zasadanie vie o tom, neuloží sa automaticky.

Vytvorme objekt používateľa s konštruktorom a potvrdíme, že ho nespravuje relácia:

Relácia session = openSession (); UserEntity userEntity = new UserEntity ("John"); assertThat (session.contains (userEntity)). isFalse ();

3.2. Vytrvalé

Objekt, ktorý sme spojili s a zasadanie je v trvalom stave. Buď sme ho uložili, alebo prečítali z kontextu vytrvalosti, takže predstavuje nejaký riadok v databáze.

Vytvorme objekt a potom použite pretrvávať spôsob, ako to urobiť perzistentným:

Relácia session = openSession (); UserEntity userEntity = new UserEntity ("John"); session.persist (userEntity); assertThat (session.contains (userEntity)). isTrue ();

Prípadne môžeme použiť uložiť metóda. Rozdiel je v tom, že pretrvávať metóda iba uloží objekt a uložiť metóda bude navyše generovať svoj identifikátor, ak je to potrebné.

3.3. Oddelený

Keď zavrieme zasadanie, všetky objekty v jeho vnútri sa oddelia. Aj keď stále predstavujú riadky v databáze, už ich nikto nespravuje zasadanie:

session.persist (userEntity); session.close (); assertThat (session.isOpen ()). isFalse (); assertThatThrownBy (() -> session.contains (userEntity));

Ďalej sa naučíme, ako ukladať prechodné a oddelené entity.

4. Uloženie a opätovné pripojenie entity

4.1. Uloženie prechodnej entity

Vytvorme novú entitu a uložme ju do databázy. Keď prvýkrát postavíme objekt, bude v prechodnom stave.

To pretrvávať náš nový subjekt, použijeme pretrvávať metóda:

UserEntity userEntity = new UserEntity ("John"); session.persist (userEntity);

Teraz vytvoríme ďalší objekt s rovnakým identifikátorom ako prvý. Tento druhý objekt je prechodný, pretože ho zatiaľ nikto nespravuje zasadanie, ale nemôžeme to dosiahnuť trvalým používaním pretrvávať metóda. Je už zastúpený v databáze, takže v kontexte vrstvy perzistencie nie je skutočne nový.

Namiesto toho použijeme zlúčiť metóda na aktualizáciu databázy a zabezpečenie perzistentnosti objektu:

UserEntity onceAgainJohn = nový UserEntity ("John"); session.merge (onceAgainJohn);

4.2. Uloženie odpojenej entity

Ak zavrieme predošlé zasadanie, naše objekty budú v odpojenom stave. Podobne ako v predchádzajúcom príklade sú zastúpené v databáze, ale v súčasnosti ich nikto nespravuje zasadanie. Môžeme ich znova urobiť perzistentnými pomocou zlúčiť metóda:

UserEntity userEntity = new UserEntity ("John"); session.persist (userEntity); session.close (); session.merge (userEntity);

5. Vnorené subjekty

Veci sa komplikujú, keď vezmeme do úvahy vnorené entity. Povedzme, že naša používateľská entita bude tiež ukladať informácie o svojom manažérovi:

verejná trieda UserEntity {@Id súkromné ​​meno reťazca; @ManyToOne súkromný manažér UserEntity; }

Keď ukladáme túto entitu, musíme myslieť nielen na stav samotnej entity, ale aj na stav vnorenej entity. Vytvorme entitu trvalého používateľa a potom nastavíme jej správcu:

UserEntity userEntity = new UserEntity ("John"); session.persist (userEntity); UserEntity manager = nový UserEntity ("Adam"); userEntity.setManager (manažér);

Ak sa ju pokúsime aktualizovať hneď, dostaneme výnimku:

assertThatThrownBy (() -> {session.saveOrUpdate (userEntity); transaction.commit ();});
java.lang.IllegalStateException: org.hibernate.TransientPropertyValueException: objekt odkazuje na neuloženú prechodnú inštanciu - uložte prechodnú inštanciu pred vyprázdnením: com.baeldung.states.UserEntity.manager -> com.baeldung.states.UserEntity 

To sa deje, pretože Hibernate nevie, čo má robiť s prechodnou vnorenou entitou.

5.1. Pretrvávajúce vnorené subjekty

Jedným zo spôsobov riešenia tohto problému je výslovne pretrvávať vnorené entity:

UserEntity manager = nový UserEntity ("Adam"); session.persist (manažér); userEntity.setManager (manažér);

Potom po vykonaní transakcie budeme môcť získať správne uloženú entitu:

transaction.commit (); session.close (); Relácia otherSession = openSession (); UserEntity savedUser = otherSession.get (UserEntity.class, "John"); assertThat (savedUser.getManager (). getName ()). isEqualTo ("Adam");

5.2. Kaskádové operácie

Prechodné vnorené entity je možné automaticky zachovať, ak nakonfigurujeme vzťah kaskáda vlastnosť správne v triede entít:

@ManyToOne (cascade = CascadeType.PERSIST) súkromný manažér UserEntity;

Teraz, keď objekt pretrvávame, bude táto operácia kaskádovo pripojená ku všetkým vnoreným entitám:

UserEntityWithCascade userEntity = nový UserEntityWithCascade ("John"); session.persist (userEntity); UserEntityWithCascade manager = nový UserEntityWithCascade ("Adam"); userEntity.setManager (manažér); // pridať prechodového manažéra k trvalej relácii používateľa.saveOrUpdate (userEntity); transaction.commit (); session.close (); Relácia otherSession = openSession (); UserEntityWithCascade savedUser = otherSession.get (UserEntityWithCascade.class, "John"); assertThat (savedUser.getManager (). getName ()). isEqualTo ("Adam");

6. Zhrnutie

V tomto tutoriáli sme sa bližšie pozreli na to, ako je režim dlhodobého spánku Session pracuje s ohľadom na stav objektu. Potom sme skontrolovali niektoré problémy, ktoré môže spôsobiť, a spôsoby ich riešenia.

Ako vždy, zdrojový kód je k dispozícii na GitHub.


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