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.