Lista stanów

A teraz zaczyna się zabawa. Będziemy badać stany obiektów Entity. Za wszystko trzeba płacić, a także za korzystanie z Hibernate. Nie sądzisz, że nauka HQL to taka cena? Nie, życie jest trochę bardziej skomplikowane.

Jeśli masz jakiś obiekt Entity, który możesz zapisać do bazy danych za pomocą Hibernate, to z punktu widzenia Hibernate obiekt ten może mieć cztery stany:

  • Przejściowy
  • Trwałe (lub zarządzane)
  • Wolnostojący
  • REMOVED

A żeby was zainteresować, dodam do tego wykładu to zdjęcie:

Przejściowy

W rzeczywistości wszystko jest znacznie prostsze niż się wydaje, choć nie bez niuansów. Na przykład każdy obiekt Entity, który został jawnie utworzony przy użyciu kodu Java i nie został załadowany z bazy danych przy użyciu Hibernate, ma status Przejściowy (przezroczysty).

EmployeeEntity employee = new EmployeeEntity();

Status Transient oznacza, że ​​Hibernate nie ma pojęcia o tym obiekcie i żadna akcja na obiekcie nie wpływa na Hibernate, ani też nie działa Hibernate na tym obiekcie.

Obiekty takie nazywane są również POJO - Plain Old Java Object . Termin ten jest często używany jako przeciwieństwo różnych obiektów o trudnym zachowaniu. Pamiętasz obiekty Moc, które stworzył Mockito? Tutaj nie są POJO.

Jeśli jakiś kod klienta działa z obiektem o statusie Transient, to ich interakcję można opisać za pomocą bardzo prostego schematu:

Trwałe lub zarządzane

Kolejnym najczęstszym przypadkiem są obiekty związane z silnikiem Hibernate. Ich status nazywa się Trwały (lub Zarządzany). Istnieją dokładnie dwa sposoby na uzyskanie obiektu o tym statusie:

  • Załaduj obiekt z Hibernacji.
  • Zapisz obiekt w hibernacji.

Przykłady:

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

Taki obiekt zwykle odpowiada jakiemuś rekordowi w bazie danych, ma identyfikator i tym podobne. Ten obiekt jest dołączony do sesji Hibernate i ogólnie może być reprezentowany nie przez rzeczywisty obiekt, ale przez pewnego rodzaju proxy.

Całkiem możliwe, że po wywołaniu metody session.load() otrzymasz z powrotem jakiś obiekt pośredniczący (proxy), a wszystkie wywołania do bazy danych będą wykonywane dopiero po wywołaniu metod tego obiektu. Ale o takich szczegółach porozmawiamy nieco później.

A interakcję między kodem klienta a obiektem w statusie Managed można opisać następującym obrazkiem:

Wolnostojący

Następnym stanem jest odłączenie obiektu od sesji. Oznacza to, że gdy obiekt został dołączony do sesji Hibernate, ale sesja została zamknięta lub transakcja została zakończona, a Hibernate nie monitoruje już tego obiektu.

Przykład:

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

W pierwszym przykładzie sesja została zamknięta. W drugim przypadku wyraźnie zaznaczyliśmy, że chcemy odłączyć obiekt od sesji za pomocą metody evict() .

Nowy schemat interakcji kod-obiekt będzie wyglądał następująco:

I tutaj robi się ciekawie. Jeśli Twój obiekt został uzyskany z Hibernate, prawdopodobnie otrzymałeś proxy zamiast prawdziwego obiektu. A ten obiekt proxy po rozłączeniu z sesją będzie generował wyjątki przy wywołaniu jego metod.

Jest to najczęstszy problem wszystkich początkujących podczas pracy z Hibernate. Podczas pracy z obiektem Entity musisz znać dokładnie w dowolnym momencie odpowiedź na takie pytania :

  • Czy masz prawdziwy obiekt, czy tylko proxy z prawdziwego obiektu?
  • Czy jesteś obecnie w trakcie transakcji, czy nie?
  • Czy jest to transakcja do odczytu i zapisu, czy transakcja tylko do odczytu?
  • Czy obiekt jest zarządzany przez mechanizm LazyLoading?
  • Które części obiektu są już załadowane do pamięci, a które zostaną załadowane po uzyskaniu dostępu?
  • W jaki sposób twój obiekt jest połączony z obiektami zależnymi?

Dobra wiadomość jest taka, że ​​przez większość czasu jest to oczywiste. Ale nadal musisz zrozumieć, jak to wszystko działa pod maską. Programowanie deklaratywne jest tym, czym jest - możesz napisać kod w 10 minut, zrozumieć, dlaczego nie działa tak, jak powinien - w 10 godzin :)

REMOVED

A ostatnim stanem, jaki może mieć obiekt Entity, jest Usunięty. Jak zapewne już się domyśliłeś z jego nazwy, jest to stan zdalnego obiektu.

Ten stan pojawia się, ponieważ jeśli usuniesz jakiś obiekt z bazy danych, to obiekt Java nie zniknie od razu nigdzie.

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