Stanja predmeta na zasjedanju hibernacije

1. Uvod

Hibernate je prikladan okvir za upravljanje trajnim podacima, ali razumijevanje internog rada ponekad može biti nezgodno.

U ovom uputstvu naučit ćemo o stanjima objekata i kako se kretati između njih. Također ćemo razmotriti probleme s kojima se možemo susresti s odvojenim entitetima i kako ih riješiti.

2. Sjednica hibernacije

The Sjednica sučelje je glavni alat koji se koristi za komunikaciju s hibernacijom. Pruža API koji nam omogućuje stvaranje, čitanje, ažuriranje i brisanje trajnih objekata. The sjednica ima jednostavan životni ciklus. Otvorimo ga, izvedemo neke operacije, a zatim zatvorimo.

Kada operiramo predmete tijekom sjednica, oni se vežu za to sjednica. Promjene koje napravimo otkrivaju se i spremaju po zatvaranju. Nakon zatvaranja, Hibernate prekida veze između objekata i sesije.

3. Stanja predmeta

U kontekstu hibernacije Sjednica, objekti mogu biti u jednom od tri moguća stanja: prolazni, postojani ili odvojeni.

3.1. Prolazno

Predmet koji nismo vezali ni za jedan sjednica je u prolaznom stanju. Budući da nikada nije nastavljen, nema nikakvu predstavu u bazi podataka. Jer ne sjednica svjestan toga, neće se automatski spremiti.

Stvorimo korisnički objekt s konstruktorom i potvrdimo da njime ne upravlja sesija:

Sjednica sesije = openSession (); UserEntity userEntity = novi UserEntity ("John"); assertThat (session.contens (userEntity)). isFalse ();

3.2. Uporan

Objekt koji smo povezali s sjednica je u postojanom stanju. Ili smo ga spremili ili pročitali iz konteksta trajnosti, tako da predstavlja neki redak u bazi podataka.

Stvorimo objekt, a zatim upotrijebimo ustrajati metoda koja će ga učiniti ustrajnim:

Sjednica sesije = openSession (); UserEntity userEntity = novi UserEntity ("John"); session.persist (userEntity); assertThat (session.contens (userEntity)). isTrue ();

Alternativno, možemo koristiti uštedjeti metoda. Razlika je u tome što ustrajati metoda samo će spremiti objekt, a uštedjeti metoda će dodatno generirati svoj identifikator ako je to potrebno.

3.3. Odvojeno

Kad zatvorimo sjednica, svi se predmeti u njemu odvoje. Iako još uvijek predstavljaju retke u bazi podataka, njima više ne upravlja nitko sjednica:

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

Dalje ćemo naučiti kako spasiti privremene i odvojene cjeline.

4. Spremanje i ponovno spajanje entiteta

4.1. Spremanje prolazne cjeline

Stvorimo novi entitet i spremimo ga u bazu podataka. Kad prvi put konstruiramo objekt, on će biti u prolaznom stanju.

Do ustrajati naš novi entitet, koristit ćemo ustrajati metoda:

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

Sada ćemo stvoriti još jedan objekt s istim identifikatorom kao i prvi. Ovaj drugi objekt je prolazan jer njime još nitko ne upravlja sjednica, ali ne možemo ga učiniti trajnim pomoću ustrajati metoda. Već je zastupljen u bazi podataka, pa zapravo nije nov u kontekstu sloja postojanosti.

Umjesto toga, koristit ćemo sjediniti metoda za ažuriranje baze podataka i učini objekt trajnim:

UserEntity OnceAgainJohn = novi UserEntity ("John"); session.merge (OnceAgainJohn);

4.2. Spremanje izdvojenog entiteta

Ako zatvorimo prethodno sjednica, naši će objekti biti u odvojenom stanju. Slično prethodnom primjeru, oni su predstavljeni u bazi podataka, ali trenutno njima ne upravlja nitko sjednica. Možemo ih učiniti upornima ponovno pomoću sjediniti metoda:

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

5. Ugnježđeni entiteti

Stvari se zakompliciraju kada uzmemo u obzir ugniježđene entitete. Recimo da će i naš korisnički entitet pohraniti podatke o svom upravitelju:

javna klasa UserEntity {@Id ime privatnog niza; @ManyToOne privatni upravitelj UserEntity; }

Kada spašavamo ovaj entitet, moramo misliti ne samo na stanje samog entiteta već i na stanje ugniježđenog entiteta. Stvorimo trajni korisnički entitet, a zatim postavimo njegovog upravitelja:

UserEntity userEntity = novi UserEntity ("John"); session.persist (userEntity); UserEntity manager = novi UserEntity ("Adam"); userEntity.setManager (upravitelj);

Ako ga sada pokušamo ažurirati, dobit ćemo izuzetak:

assertThatThrownBy (() -> {session.saveOrUpdate (userEntity) ;action.commit ();});
java.lang.IllegalStateException: org.hibernate.TransientPropertyValueException: objekt se odnosi na nespremljenu prijelaznu instancu - spremite prijelaznu instancu prije ispiranja: com.baeldung.states.UserEntity.manager -> com.baeldung.states.UserEntity 

To se događa jer Hibernate ne zna što učiniti s prijelaznim ugniježđenim entitetom.

5.1. Trajni ugniježđeni entiteti

Jedan od načina rješavanja ovog problema je izričito postojanje ugniježđenih entiteta:

UserEntity manager = novi UserEntity ("Adam"); session.persist (menadžer); userEntity.setManager (upravitelj);

Tada ćemo, nakon izvršavanja transakcije, moći dohvatiti ispravno spremljeni entitet:

transakcija.commit (); session.close (); Sjednica otherSession = openSession (); UserEntity savedUser = otherSession.get (UserEntity.class, "John"); assertThat (savedUser.getManager (). getName ()). isEqualTo ("Adam");

5.2. Kaskadne operacije

Privremeni ugniježđeni entiteti mogu se automatski održavati ako konfiguriramo odnos kaskada svojstvo ispravno u klasi entiteta:

@ManyToOne (cascade = CascadeType.PERSIST) privatni upravitelj UserEntity;

Sada, kada istrajemo na objektu, ta će operacija biti kaskadno prenesena na sve ugniježđene entitete:

UserEntityWithCascade userEntity = novi UserEntityWithCascade ("John"); session.persist (userEntity); UserEntityWithCascade manager = novi UserEntityWithCascade ("Adam"); userEntity.setManager (upravitelj); // dodavanje privremenog upravitelja trajnoj korisničkoj sesiji.saveOrUpdate (userEntity); transakcija.commit (); session.close (); Sjednica otherSession = openSession (); UserEntityWithCascade savedUser = otherSession.get (UserEntityWithCascade.class, "John"); assertThat (savedUser.getManager (). getName ()). isEqualTo ("Adam");

6. Sažetak

U ovom uputstvu pobliže smo pogledali kako zimski san Sjednica radi s obzirom na stanje objekta. Zatim smo pregledali neke probleme koje on može stvoriti i kako ih riješiti.

Kao i uvijek, izvorni kod dostupan je na GitHub-u.


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