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);
//po załadowaniu stan obiektu to Persisted
session.remove(employee);
//po usunięciu stan obiektu to Usunięto
session.save(employee);
// a teraz ponownie utrzymał się
session.close();
// a teraz stan Odłączony
GO TO FULL VERSION