Lista statelor

Și acum începe distracția. Vom studia stările obiectelor Entity. Trebuie să plătiți pentru tot și pentru utilizarea Hibernate. Nu crezi că învățarea HQL este un astfel de preț? Nu, viața este puțin mai complicată.

Dacă aveți un fel de obiect Entity pe care îl puteți salva în baza de date folosind Hibernate, atunci din punctul de vedere al Hibernate, acest obiect poate avea patru stări:

  • Tranzitoriu
  • Persistent (sau gestionat)
  • Detașat
  • Îndepărtat

Și pentru a vă interesa, voi adăuga această imagine la această prelegere:

Tranzitoriu

De fapt, totul este mult mai simplu decât pare, deși nu lipsit de nuanțe. De exemplu, fiecare obiect Entity pe care l-ați creat în mod explicit folosind cod Java și nu l-ați încărcat din baza de date folosind Hibernate, are o stare Tranzitorie (transparentă).

EmployeeEntity employee = new EmployeeEntity();

Starea Tranzitorie înseamnă că Hibernate nu are nicio idee despre acest obiect și nicio acțiune asupra obiectului nu afectează Hibernate, nici munca Hibernate asupra acestui obiect.

Astfel de obiecte mai sunt numite POJO - Plain Old Java Object . Termenul este adesea folosit ca opusul diferitelor obiecte cu comportament dificil. Îți amintești de obiectele Moc pe care Mockito le-a creat? Aici nu sunt POJO.

Dacă un cod client funcționează cu un obiect cu starea Tranzitorie, atunci interacțiunea lor poate fi descrisă printr-o schemă super simplă:

Persistent sau Gestionat

Următorul caz cel mai frecvent este obiectele legate de motorul Hibernate. Statutul lor se numește Persistent (sau Gestionat). Există exact două moduri de a obține un obiect cu această stare:

  • Încărcați obiectul din Hibernate.
  • Salvați obiectul în Hibernare.

Exemple:

Employee employee = session.load(Employee.class, 1);
Employee employee = new Employee ();
session.save(employee);

Un astfel de obiect corespunde de obicei unui fel de înregistrare din baza de date, are un ID și altele asemenea. Acest obiect este atașat sesiunii Hibernate și, în general, poate fi reprezentat nu printr-un obiect real, ci printr-un fel de proxy.

Este foarte posibil ca după apelarea metodei session.load() să primiți înapoi un obiect stub (proxy), iar toate apelurile către baza de date să fie efectuate numai după apelarea metodelor acestui obiect. Dar despre astfel de detalii vom vorbi puțin mai târziu.

Iar interacțiunea dintre codul clientului și obiectul din starea Gestionat poate fi descrisă cu următoarea imagine:

Detașat

Următoarea stare este atunci când obiectul a fost detașat din sesiune. Adică, odată ce obiectul a fost atașat la sesiunea Hibernate, dar apoi sesiunea a fost închisă sau tranzacția sa încheiat, iar Hibernate nu mai monitorizează acest obiect.

Exemplu:

session.close();
session.evict(entity);

În primul exemplu, sesiunea a fost închisă. În al doilea caz, am indicat în mod explicit că dorim să detașăm obiectul din sesiune folosind metoda evict() .

Noua schemă de interacțiune cod-obiect va arăta astfel:

Și aici devine interesant. Dacă obiectul tău a fost obținut din Hibernate, atunci este probabil să ți s-a dat un proxy în loc de un obiect real. Și acest obiect proxy, după deconectarea de la sesiune, va arunca excepții atunci când metodele sale sunt apelate.

Aceasta este cea mai comună problemă pentru toți începătorii când lucrează cu Hibernate. Trebuie să știți exact la orice moment răspunsul la întrebări de genul acesta atunci când lucrați cu un obiect Entity :

  • Aveți un obiect real sau doar un proxy de la un obiect real?
  • Sunteți sau nu într-o tranzacție în prezent?
  • Este o tranzacție de citire-scriere sau o tranzacție doar de citire?
  • Obiectul este gestionat de mecanismul LazyLoading?
  • Ce părți ale obiectului sunt deja încărcate în memorie și ce părți vor fi încărcate atunci când sunt accesate?
  • Cum este conectat obiectul tău la obiectele dependente?

Vestea bună este că de cele mai multe ori este evident. Dar tot trebuie să înțelegeți cum funcționează totul sub capotă. Programarea declarativă este ceea ce este - poți scrie cod în 10 minute, înțelege de ce nu funcționează așa cum ar trebui - în 10 ore :)

Îndepărtat

Și ultima stare pe care o poate avea obiectul Entității este Eliminată. După cum probabil ați ghicit deja din numele său, aceasta este starea unui obiect aflat la distanță.

Această stare apare datorită faptului că, dacă ștergeți un obiect din baza de date, atunci obiectul Java nu va dispărea imediat nicăieri.

Employee employee = session.load(Employee.class, 1);
//after loading the object's state is Persisted

session.remove(employee);
//after deletion, the state of the object is Removed

session.save(employee);
//and now Persisted again

session.close();
//and now the Detached state