Hibernate 3.6 - Sitzung.get() vs-Sitzung.load()
Ich versuche zu verstehen, was der Unterschied ist im zurückgegebenen Objekt und Verhalten von Hibernate 3.6 session.get()
und session.load()
.
Aus der javadoc:
get():
Rückkehr der persistenten Instanz des angegebenen entity-Klasse mit der
gegebenen id, oder null, falls es keine solche persistente Instanz. (Wenn
die Instanz ist bereits im Zusammenhang mit der Sitzung zurück, dass
Instanz. Diese Methode kehrt nie zurück ein nicht initialisierter Instanz.)
load():
Rückkehr der persistenten Instanz des angegebenen entity-Klasse mit der
angegebenen Identifikator, unter der Annahme, dass die Instanz vorhanden ist. Diese Methode könnte
Rückkehr einer Proxy-Instanz initialisiert on-demand, wenn eine
nicht-id-Methode zugegriffen wird.
Ich habe drei Fragen:
-
In der javadoc nicht sagen, wenn
load()
zurückgeben könnte ein proxy - gibt es eine Möglichkeit, es zu wissen im Voraus? -
Wenn
load()
gibt einen proxy - das heißtload()
nicht auf die Datenbank zugreifen, bin ich richtig? Wenn ich dann was zur Verfügung gestelltload()
mit einem Bezeichner, der nicht in der Datenbank vorhanden sind? Ich will nun in der Sitzung einen proxy mit einer ungültigen ID (ohne eine Ausnahme). Ich will jetzt lassen anderen persistenten Instanz zeigen auf, dass der proxy - ist es, zur Arbeit zu gehen? Für dieses Szenario brauche ich nicht zum initialisieren der proxy, ich brauche nur seine id (die ich habe, obwohl seine ungültig, da es nicht in der Datenbank). Also ich denke, ich Frage, ob meine Beschreibung richtig ist, und muss ich immer den check-out nachload()
das zurückgegebene Objekt mitisInitialized()
um sicherzustellen, dass es stellt eine gültige Einheit (oder zumindest eine gültige proxy), d.h. mit einer gültigen ID. -
Auch, was passiert, wenn
load()
gibt einen proxy - also der proxy ist die Instanz, die bereits im Zusammenhang mit der Sitzung. Dann nach der Beschreibung desget()
: "Wenn die Instanz bereits im Zusammenhang mit der Sitzung zurück, dass die Instanz." - also nichtget()
Gegenzug den proxy? Da nach der Beschreibung desget()
: "Diese Methode kehrt nie zurück ein nicht initialisierter Instanz".
Dank!
UPDATE
Sind die folgenden korrekt?
(A) ich denke, dass beide load()
und get()
wird zunächst versuchen, überprüfen Sie die session-cache, bevor Sie gehen, um die DB - so wäre es nicht Recht zu sagen, dass einer von Ihnen immer trifft der DB, oder gibt immer einen proxy.
(B) Eine initialisierte proxy ist nicht das gleiche wie die ursprüngliche Instanz, wie Sie hier Lesen können: http://blog.xebia.com/2008/03/08/advanced-hibernate-proxy-pitfalls/
Du musst angemeldet sein, um einen Kommentar abzugeben.
(1) , (3) :
Ja. Du hast Recht .Sowohl die
load()
undget()
wird zunächst überprüft, ob es eine Instanz mit dem gleichen PK wird beibehalten, in der Sitzung.Wenn ja , einfach zurück, die Instanz aus der session. (Kann es sein das der proxy oder die eigentliche entity-Klasse, Instanz)
Wenn Nein ,
load()
erstellen und geben Sie einen proxy währendget()
auf DB und gibt die Instanz der eigentlichen entity-Klasse .Das zurückgegebene Objekt aus den beiden Methoden in Verbindung gebracht werden und bleiben in der session danach.
So , ob
get()
oderload()
Gegenzug proxy oder die wirkliche Einheit der Klasse hängt davon ab, ob Sie mit get() oder load() der Instanz der gleichen PK in der aktuellen Sitzung zum ersten mal.Können Sie Beweis dieses Verhalten, indem Sie die folgenden test:
Wenn es ein proxy , der gedruckten Klassennamen wird nicht die gleiche sein, wie die eigentliche entity-Klasse name. Ändern Sie einfach die Reihenfolge der Ausführung von zu
load()
undget()
um den Effekt zu sehen.(2):
Wenn die load () - gibt einen proxy , es wird nicht auf die DB während
load()
.Der proxy greift nur auf die DB, wenn Ihre zugeordneten Eigenschaften neben der PK zugegriffen werden und es sind keine Instanzen mit dem gleichen PK-Wert wird mit der Sitzung verknüpft.Nachdem der proxy greift auf die DB-Instanz mit der gleichen PK der proxy wird im Zusammenhang mit der Tagung .Wenn Sie also die anderen Eigenschaften vom proxy erneut, oder verwenden Sie
get()
um die Instanz für die gleichen PK , die DB nicht zugegriffen, als die Werte aus der session.Beispiel:
Wenn Sie
load()
eine Instanz mit der ungültigen ID und dann auf die Eigenschaften oder das aufrufen einer Methode (wieisInitialized()
) auf diesem proxy ,ObjectNotFoundException
geworfen werden. Also, wenn Sie fangen kannObjectNotFoundException
bedeutet es , einen proxy geladen wird, mit einer ungültigen ID.Wenn Sie sicherstellen möchten, dass die ID gültig ist, während der Laufzeit , die Sie verwenden sollten
get()
und überprüfen Sie, ob die zurückgegebene Instanz ist null .load()
ist hilfreich beim festlegen der foreign key-Einschränkung. Sehen dieseget()
nachload()
zurück initialisiert proxy, oder einfach nur eine initialisierte Instanz? Denn wenn es das später, dann haben wir jetzt in der Sitzung zwei Objekte die gleiche ID (die proxy-und die Instanz). BTW ich weiß, es ist möglich, zwei Stellvertreter, die für die gleiche DB wie die ID kann man hier nachlesen: docs.jboss.org/hibernate/core/3.6/reference/en-US/html_single unter dem text "Zweitens, ist es möglich, zu brechen proxy". -- Lesen Sie dazu mehr im UPDATE in meiner ursprünglichen Frage.get()
undload()
.Siehe mein update bitteload()
wird NIE werfen dieser Ausnahme: wenn die Instanz/proxy ist in den session-cache zurück, sonst wird es ein Proxykonto erstellen (unabhängig davon, ob ID in DB) - es wäre richtig zu sagen, dass ein proxy, der zurückgegeben wird, durchload()
vielleicht werfen diese Ausnahme (irgendwann nachload()
hat bereits zurückgegeben) - ist mein Verständnis korrekt? Wenn dem so ist, in der javadoc über diesen Mechanismus ist irreführend, oder ganz offen gesagt, falsch.load()
ein Element mit der ungültigen ID mitsession.load(Item.class, someInvalidId);
gibt es keineObjectNotFoundException
geworfen in dieser Zeile DieObjectNotFoundException
geworfen werden, wenn ich auf die Eigenschaften (neben der PK-Eigenschaft) der zurückgegebene proxy .