Antworten:
Durch das Leeren der Sitzung wird der Ruhezustand gezwungen, den speicherinternen Status von Session
mit der Datenbank zu synchronisieren (dh Änderungen in die Datenbank zu schreiben). Standardmäßig löscht Hibernate Änderungen automatisch für Sie:
Wenn Sie das explizite Löschen zulassen, erhalten Sie Session
eine genauere Kontrolle, die unter bestimmten Umständen erforderlich sein kann (um eine ID zuzuweisen, um die Größe der Sitzung zu steuern, ...).
id = session.save(obj);
und die Transaktion in der nächsten Zeile festgeschrieben wird, aber obj wird nicht gespeichert an die DB, warum? 2) Ich habe obj session.save(obj);
mit commit gespeichert und bei der Rückgabe verwendet. return obj.getprimaryID();
In diesem Fall wird obj in der Datenbank gespeichert. Warum passiert dieses Verhalten?
Wie in den obigen Antworten zu Recht gesagt, telefonisch flush()
erzwingen wir Ruhezustand, um die SQL-Befehle in der Datenbank auszuführen. Aber verstehen Sie, dass Änderungen noch nicht "festgeschrieben" sind. Wenn Sie also nach dem Flush und vor dem Commit direkt auf die Datenbank zugreifen (z. B. über die SQL-Eingabeaufforderung) und die geänderten Zeilen überprüfen, werden die Änderungen NICHT angezeigt.
Dies entspricht dem Öffnen von 2 SQL-Befehlssitzungen. Und Änderungen, die in einer Sitzung vorgenommen wurden, sind für andere erst sichtbar, wenn sie festgeschrieben wurden.
Ich weiß nur, dass session.flush()
unsere Anweisungen beim Aufruf in der Datenbank ausgeführt, aber nicht festgeschrieben werden.
Angenommen, wir rufen keine flush()
Methode für das Sitzungsobjekt auf, und wenn wir die Festschreibungsmethode aufrufen, werden intern Anweisungen in der Datenbank ausgeführt und anschließend festgeschrieben.
commit=flush+commit
(bei Funktionalität)
Daher komme ich zu dem Schluss, dass beim Aufrufen der Methode flush () für das Sitzungsobjekt kein Commit ausgeführt wird, sondern die Datenbank erreicht und die Abfrage ausgeführt wird und auch ein Rollback ausgeführt wird.
Zum Festschreiben verwenden wir commit () für das Transaktionsobjekt.
Durch das Leeren der Sitzung werden die Daten, die sich derzeit in der Sitzung befinden, mit den Daten in der Datenbank synchronisiert.
Mehr auf der Hibernate-Website:
flush()
Dies ist nützlich, da es absolut keine Garantie dafür gibt, wann die Sitzung die JDBC-Aufrufe ausführt, sondern nur die Reihenfolge, in der sie ausgeführt werden - außer Sie verwenden flush()
.
Sie können verwenden, um flush
zu erzwingen, dass Validierungsbeschränkungen an einem bekannten Ort realisiert und erkannt werden, anstatt wenn die Transaktion festgeschrieben wird. Es kann sein, dass dies commit
implizit von einer Framework-Logik, einer deklarativen Logik, dem Container oder einer Vorlage aufgerufen wird. In diesem Fall kann es schwierig sein, eine ausgelöste Ausnahme abzufangen und zu behandeln (sie kann im Code zu hoch sein).
Wenn Sie beispielsweise save()
ein neues EmailAddress-Objekt verwenden, dessen Adresse eine eindeutige Einschränkung aufweist, wird erst beim Festschreiben eine Fehlermeldung angezeigt.
Beim Aufrufen flush()
wird das Einfügen der Zeile erzwungen, und es wird eine Ausnahme ausgelöst, wenn ein Duplikat vorhanden ist.
Sie müssen die Sitzung jedoch nach der Ausnahme zurücksetzen.
Ich möchte nur alle oben gegebenen Antworten zusammenfassen und die Flush () -Methode mit Session.save () verknüpfen, um mehr Bedeutung zu verleihen
Hibernate save () kann verwendet werden, um die Entität in der Datenbank zu speichern. Wir können diese Methode außerhalb einer Transaktion aufrufen. Deshalb mag ich diese Methode nicht, um Daten zu speichern. Wenn wir dies ohne Transaktion verwenden und zwischen Entitäten kaskadieren, wird nur die primäre Entität gespeichert, es sei denn, wir leeren die Sitzung.
flush (): Erzwingt das Leeren der Sitzung. Es wird verwendet, um Sitzungsdaten mit der Datenbank zu synchronisieren.
Wenn Sie session.flush () aufrufen, werden die Anweisungen in der Datenbank ausgeführt, aber nicht festgeschrieben. Wenn Sie session.flush () nicht aufrufen und session.commit () aufrufen, führt die intern commit () -Methode die Anweisung aus und schreibt fest.
Also commit () = flush + commit. Session.flush () führt also nur die Anweisungen in der Datenbank aus (aber keine Commits) und Anweisungen sind NICHT MEHR IM SPEICHER. Es zwingt die Sitzung nur zum Spülen.
Einige wichtige Punkte:
Wir sollten das Speichern außerhalb der Transaktionsgrenze vermeiden, da sonst zugeordnete Entitäten nicht gespeichert werden, was zu Dateninkonsistenzen führt. Es ist ganz normal, das Leeren der Sitzung zu vergessen, da keine Ausnahmen oder Warnungen ausgegeben werden. Standardmäßig löscht Hibernate Änderungen automatisch für Sie: Vor einigen Abfrageausführungen, wenn eine Transaktion festgeschrieben wird. Wenn Sie die Sitzung explizit löschen, erhalten Sie eine genauere Kontrolle, die unter bestimmten Umständen erforderlich sein kann (um eine ID zuzuweisen, um die Größe der Sitzung zu steuern )
Die flush()
Methode bewirkt, dass der Ruhezustand die Sitzung leert. Sie können den Ruhezustand mithilfe der setFlushMode()
Methode so konfigurieren, dass der Spülmodus für die Sitzung verwendet wird. Um den Flush-Modus für die aktuelle Sitzung abzurufen, können Sie die getFlushMode()
Methode verwenden. Um zu überprüfen, ob die Sitzung verschmutzt ist, können Sie die isDirty()
Methode verwenden. Standardmäßig verwaltet Hibernate das Leeren der Sitzungen.
Wie in der Dokumentation angegeben:
https://docs.jboss.org/hibernate/orm/5.2/userguide/html_single/chapters/flushing/Flushing.html
Spülen
Beim Flushing wird der Status des Persistenzkontexts mit der zugrunde liegenden Datenbank synchronisiert. Der
EntityManager
und der RuhezustandSession
stellen eine Reihe von Methoden bereit, mit denen der Anwendungsentwickler den persistenten Status einer Entität ändern kann.Der Persistenzkontext fungiert als Transaktions-Write-Behind-Cache, der jede Änderung des Entitätsstatus in die Warteschlange stellt. Wie bei jedem Write-Behind-Cache werden Änderungen zuerst im Arbeitsspeicher angewendet und während der Flush-Zeit mit der Datenbank synchronisiert. Die Flush-Operation übernimmt jede Änderung des Entitätsstatus und übersetzt sie in ein
INSERT
,UPDATE
oderDELETE
Aussage.Die Spülstrategie wird durch den FlushMode der aktuell ausgeführten Hibernate-Sitzung angegeben. Obwohl JPA nur zwei Spülstrategien (
AUTO
undCOMMIT
) definiert, verfügt Hibernate über ein viel breiteres Spektrum an Spültypen:
ALWAYS
: Leert die Sitzung vor jeder Abfrage.AUTO
: Dies ist der Standardmodus und löscht die Sitzung nur bei Bedarf.COMMIT
: Die Sitzung versucht, das Löschen zu verzögern, bis die aktuelle Transaktion festgeschrieben wird, obwohl sie möglicherweise auch vorzeitig gelöscht wird.MANUAL
: Die Sitzungsbereinigung wird an die Anwendung delegiert, dieSession.flush()
explizit aufgerufen werden muss, um die Änderungen des Persistenzkontexts anzuwenden.Standardmäßig verwendet Hibernate den
AUTO
Flush-Modus, der unter folgenden Umständen einen Flush auslöst:
- vor dem Festschreiben einer Transaktion;
- vor dem Ausführen einer JPQL / HQL-Abfrage, die sich mit den Entitätsaktionen in der Warteschlange überschneidet;
- bevor Sie eine native SQL-Abfrage ausführen, für die keine Synchronisierung registriert ist.
Anrufen EntityManager#flush
hat Nebenwirkungen . Es wird bequem für Entitätstypen mit generierten ID-Werten (Sequenzwerten) verwendet: Eine solche ID ist nur bei Synchronisation mit der zugrunde liegenden Persistenzschicht verfügbar. Wenn diese ID vor dem Ende der aktuellen Transaktion erforderlich ist (z. B. zu Protokollierungszwecken), muss die Sitzung geleert werden.