web-dev-qa-db-de.com

Wie erkennt der Ruhezustand den Verschmutzungszustand eines Entitätsobjekts?

Verwenden Sie eine Art Bytecode-Modifikation für die ursprünglichen Klassen?

Oder wird im Ruhezustand der Zustand durch Vergleichen des angegebenen Objekts mit der zuvor beibehaltenen Version wiederhergestellt?

Ich habe ein Problem mit den Methoden hashCode() und equals() für komplizierte Objekte. Ich denke, es wäre sehr langsam, Hash-Code zu berechnen, wenn das Objekt Auflistungsmitglieder hat, und auch zyklische Verweise sind ein Problem.

Wenn Hibernate hashCode()/equals() nicht verwendet, um den fehlerhaften Zustand zu überprüfen, sollte ich wohl equals()/hashCode() nicht für das verwenden Entity-Objekt (kein Wert-Objekt), aber ich habe auch Angst, wenn derselbe Operator (==) nicht ausreicht.

Die Fragen sind also:

  1. Woher weiß der Ruhezustand, ob eine Eigenschaft eines Objekts geändert wurde?

  2. Schlagen Sie vor, die hashCode()/equals() -Methoden für komplizierte Objekte zu überschreiben? Was ist, wenn sie zyklische Referenzen enthalten?

    Und auch,

  3. Wäre hashCode()/equals() mit nur dem Feld id ausreichend?

58
Xiè Jìléi

Hibernate verwendet eine Strategie namens inspection. Dies ist im Grunde genommen Folgendes: Wenn ein Objekt aus der Datenbank geladen wird, wird ein Snapshot davon im Speicher aufbewahrt. Wenn die Sitzung beendet ist, vergleicht Hibernate den gespeicherten Snapshot mit dem aktuellen Status. Wenn sie sich unterscheiden, wird das Objekt als fehlerhaft markiert und ein geeigneter SQL-Befehl in die Warteschlange gestellt. Wenn das Objekt noch vorübergehend ist, ist es immer verschmutzt.

Quelle: Buch Hibernate in Action (Anhang B: ORM-Implementierungsstrategien)

Es ist jedoch wichtig zu beachten, dass die Dirty-Prüfung von Hibernate unabhängig von den Methoden equals/hascode ist. Hibernate betrachtet diese Methoden überhaupt nicht (außer bei Verwendung von Java.util.Set, dies hat jedoch nichts mit Dirty-Checking zu tun, sondern nur mit der Collections-API). Der oben erwähnte Status-Snapshot ähnelt einem Array von Werten. Es wäre eine sehr schlechte Entscheidung, einen solchen Kernaspekt des Frameworks den Entwicklern zu überlassen (um ehrlich zu sein, sollten sich Entwickler nicht um Dirty-Checks kümmern). Es erübrigt sich zu erwähnen, dass equals/hascode auf viele Arten entsprechend Ihren Anforderungen implementiert werden kann. Ich empfehle Ihnen, das zitierte Buch zu lesen, in dem der Autor Gleichheits-/Hascode-Implementierungsstrategien bespricht. Sehr aufschlussreiche Lektüre.

93
Antonio

Standardmäßige Dirty-Prüfung im Ruhezustand vergleicht alle zugeordneten Eigenschaften aller aktuell angehängten Entitäten mit ihren anfänglichen Ladezeitwerten.

Sie können diesen Prozess in der folgenden Abbildung besser veranschaulichen:

Default automatic dirty checking

18
Vlad Mihalcea

Der Ruhezustand führt eine Feld-für-Feld-Überprüfung durch, um die Verschmutzung einer Entität zu bestimmen.

HashCode/equals kommen also überhaupt nicht ins Bild.

Tatsächlich kann die Feld-für-Feld-Dirty-Prüfung durch Hibernate in Bezug auf die Leistung ziemlich kostspielig sein.

So bietet es Schnittstellen wie Strategy oder Interceptor.findDirty (), um dasselbe zu handhaben.

Der folgende Beitrag erläutert dies ausführlicher (zusammen mit einigen Ideen für Anwendungen zur vollständigen Optimierung ): http: //prismoskills.appspot.com/lessons/Hibernate/Chapter_20_ -_Dirty_checking.jsp

7
user2250246