Liste der Staaten

Und jetzt beginnt der Spaß. Wir werden die Zustände von Entity-Objekten untersuchen. Sie müssen für alles bezahlen, auch für die Nutzung von Hibernate. Denken Sie nicht, dass das Erlernen von HQL so teuer ist? Nein, das Leben ist etwas komplizierter.

Wenn Sie über ein Entity-Objekt verfügen, das Sie mithilfe von Hibernate in der Datenbank speichern können, kann dieses Objekt aus Sicht von Hibernate vier Zustände haben:

  • Vorübergehend
  • Persistent (oder verwaltet)
  • Losgelöst
  • ENTFERNT

Und um Sie zu interessieren, werde ich dieses Bild zu diesem Vortrag hinzufügen:

Vorübergehend

Tatsächlich ist alles viel einfacher als es scheint, wenn auch nicht ohne Nuancen. Beispielsweise hat jedes Entity-Objekt, das Sie explizit mit Java-Code erstellt und nicht mit Hibernate aus der Datenbank geladen haben, den Status „Transient“ (transparent).

EmployeeEntity employee = new EmployeeEntity();

Der Status „Transient“ bedeutet, dass Hibernate keine Ahnung von diesem Objekt hat und keine Aktion an dem Objekt Auswirkungen auf Hibernate hat, ebenso wenig wie die Arbeit von Hibernate an diesem Objekt.

Solche Objekte werden auch POJO – Plain Old Java Object genannt . Der Begriff wird oft als Gegenteil von verschiedenen Objekten mit kniffligem Verhalten verwendet. Erinnern Sie sich an die Moc-Objekte, die Mockito erstellt hat? Hier sind sie nicht POJO.

Wenn ein Client-Code mit einem Objekt mit dem Status „Transient“ arbeitet, kann seine Interaktion durch ein supereinfaches Schema beschrieben werden:

Persistent oder verwaltet

Der zweithäufigste Fall sind Objekte, die mit der Hibernate-Engine in Zusammenhang stehen. Ihr Status wird „Persistent“ (oder „Managed“) genannt. Es gibt genau zwei Möglichkeiten, ein Objekt mit diesem Status zu erhalten:

  • Objekt aus dem Ruhezustand laden.
  • Objekt im Ruhezustand speichern.

Beispiele:

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

Ein solches Objekt entspricht normalerweise einer Art Datensatz in der Datenbank, es hat eine ID und dergleichen. Dieses Objekt ist an die Hibernate-Sitzung angehängt und kann im Allgemeinen nicht durch ein reales Objekt, sondern durch eine Art Proxy dargestellt werden.

Es ist durchaus möglich, dass Sie nach dem Aufruf der Methode session.load() ein Stub-Objekt (Proxy) zurückerhalten und alle Aufrufe an die Datenbank erst nach dem Aufruf der Methoden dieses Objekts ausgeführt werden. Aber über solche Details werden wir etwas später sprechen.

Und die Interaktion zwischen dem Client-Code und dem Objekt im verwalteten Status kann mit dem folgenden Bild beschrieben werden:

Losgelöst

Der nächste Status ist, wenn das Objekt von der Sitzung getrennt wurde. Das heißt, sobald das Objekt an die Hibernate-Sitzung angehängt wurde, dann aber die Sitzung geschlossen oder die Transaktion beendet wurde und Hibernate dieses Objekt nicht mehr überwacht.

Beispiel:

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

Im ersten Beispiel wurde die Sitzung geschlossen. Im zweiten Fall haben wir explizit angegeben, dass wir das Objekt mithilfe der Methode evict() von der Sitzung trennen möchten .

Das neue Code-Objekt-Interaktionsschema sieht folgendermaßen aus:

Und hier wird es interessant. Wenn Ihr Objekt von Hibernate bezogen wurde, wurde Ihnen wahrscheinlich ein Proxy anstelle eines echten Objekts gegeben. Und dieses Proxy-Objekt löst nach dem Trennen der Sitzung Ausnahmen aus, wenn seine Methoden aufgerufen werden.

Dies ist das häufigste Problem aller Einsteiger bei der Arbeit mit Hibernate. Wenn Sie mit einem Entity-Objekt arbeiten, müssen Sie jederzeit die Antwort auf Fragen wie diese genau wissen :

  • Haben Sie ein reales Objekt oder nur einen Ersatz für ein reales Objekt?
  • Befinden Sie sich gerade in einer Transaktion oder nicht?
  • Handelt es sich um eine Lese-Schreib-Transaktion oder eine schreibgeschützte Transaktion?
  • Wird das Objekt vom LazyLoading-Mechanismus verwaltet?
  • Welche Teile des Objekts sind bereits in den Speicher geladen und welche Teile werden beim Zugriff geladen?
  • Wie ist Ihr Objekt mit abhängigen Objekten verbunden?

Die gute Nachricht ist, dass es meistens offensichtlich ist. Aber Sie müssen immer noch verstehen, wie alles unter der Haube funktioniert. Deklarative Programmierung ist, was sie ist – Sie können Code in 10 Minuten schreiben und verstehen, warum er nicht so funktioniert, wie er sollte – in 10 Stunden :)

ENTFERNT

Und der letzte Status, den Ihr Entity-Objekt haben kann, ist „Entfernt“. Wie Sie wahrscheinlich schon anhand des Namens erraten haben, ist dies der Zustand eines entfernten Objekts.

Dieser Zustand entsteht dadurch, dass das Java-Objekt nicht sofort irgendwo verschwindet, wenn Sie ein Objekt aus der Datenbank löschen.

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