Wenn Hibernate eine Session spült, wie entscheidet es, welche in der Session-Objekte verschmutzt sind?

StackOverflow https://stackoverflow.com/questions/82429

Frage

Mein Verständnis von Hibernate ist, dass Objekte aus dem DB geladen werden sie in die Session hinzugefügt werden. An verschiedenen Stellen, je nach Konfiguration, ist die Sitzung gespült. An diesem Punkt sind modifizierte Objekte in die Datenbank geschrieben.

Wie Hibernate entscheiden, welche Objekte sind ‚schmutzig‘ und müssen geschrieben werden?

Hat die von Hibernate Intercept Zuweisungen Felder erzeugen Proxies und das Objekt zu einer schmutzigen Liste in der Session hinzufügen?

Oder Hibernate in der Session an jedem Objekt suchen und vergleicht sie mit den Objekten Urzustand?

Oder etwas ganz anderes?

War es hilfreich?

Lösung

Hibernate funktioniert / kann Bytecode Generation verwenden (CGLIB), so dass er weiß, ein Feld so schnell schmutzig ist, wie Sie die Setter nennen (oder sogar auf das Feld AFAICT zuweisen).

Dies markiert sofort das Feld / Objekt als schmutzig, aber die Anzahl der Objekte nicht verringern, die während bündig schmutzig-geprüft sein müssen. Denn es macht nicht ist die Umsetzung von org.hibernate.engine.EntityEntry.requiresDirtyCheck() auswirken. Es noch hat einen Feld-für-Feld Vergleich für Schmutzigkeit zu überprüfen.

sagen, dass ich die oben basierend auf einer aktuellen Schleppnetz durch den Quellcode (3.2.6GA), mit dem, was die Glaubwürdigkeit, die hinzufügt. Sehenswürdigkeiten in der Nähe sind:

  • SessionImpl.flush() löst ein onFlush() Ereignis.
  • SessionImpl.list() ruft autoFlushIfRequired(), die ein onAutoFlush() Ereignis auslöst. (Auf den Tischen-of-Interest). Das heißt, Abfragen einen Flush aufrufen kann. Interessanterweise tritt kein Flush, wenn es keine Transaktion ist.
  • Diese beiden Ereignisse enden schließlich in AbstractFlushingEventListener.flushEverythingToExecutions() auf, die (neben anderen interessanten Orten) an flushEntities() bis endet.
  • , die über jede Entität Schleifen in der Sitzung (source.getPersistenceContext().getEntityEntries()) Aufruf DefaultFlushEntityEventListener.onFlushEntity().
  • Sie schließlich bei dirtyCheck() enden. Diese Methode hat einige Optimierungen WRT macht schmutzig Fahnen CGLIB, aber wir haben immer noch zu Ende über jede Entität Looping nach oben.

Andere Tipps

Ruhezustand eine Momentaufnahme des Zustands eines jeden Objekts, das in die Sitzung geladen wird. Auf flush, wird jedes Objekt in der Session mit seinem entsprechenden Schnappschuß im Vergleich zu bestimmen, welche schmutzig sind. SQL-Anweisungen ausgegeben werden, je nach Bedarf, und die Schnappschüsse werden aktualisiert, um den Zustand der (jetzt sauber) Session Objekte zu reflektieren.

Werfen Sie einen Blick auf org.hibernate.event.def.DefaultFlushEntityEventListener.dirtyCheck Jedes Element in der Sitzung geht auf diese Methode, um festzustellen, ob es schmutzig ist oder nicht mit einer unberührten Version (eine aus dem Cache oder aus der Datenbank) durch einen Vergleich.

Standard schmutzig Prüfmechanismus Hibernate Strom angebracht Einheiten durchlaufen wird und passen Sie alle Eigenschaften gegen ihre anfänglichen Ladezeitwerte.

Sie können diesen Prozess besser im folgende Diagramm visualisieren:

Standard automatische schmutzig Prüfung

Diese Antworten sind unvollständig (im besten Fall - ich bin kein Experte hier). Wenn Sie eine Hib-Mann Einheit in Ihrer Sitzung haben, können Sie nichts tun, um es, können Sie immer noch ein Update herausgegeben, wenn Sie () auf sie speichern nennen. wann? wenn eine andere Sitzung Updates, die zwischen load () und speichern Objekt (). hier ist mein Beispiel dafür: Hibernate setzt Dirty-Flag obwohl Client-Wert nicht

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top