Während eines Ruhezustands lade Session
ich einige Objekte und einige von ihnen werden aufgrund des verzögerten Ladens als Proxys geladen. Es ist alles in Ordnung und ich möchte das faule Laden nicht ausschalten.
Aber später muss ich einige der Objekte (eigentlich ein Objekt) per RPC an den GWT-Client senden. Und es kommt vor, dass dieses konkrete Objekt ein Proxy ist. Also muss ich daraus ein echtes Objekt machen. Ich kann im Ruhezustand keine Methode wie "materialisieren" finden.
Wie kann ich einige der Objekte von Proxys zu Reals machen, die ihre Klasse und ID kennen?
Im Moment besteht die einzige Lösung darin, dieses Objekt aus dem Cache von Hibernate zu entfernen und neu zu laden, aber es ist aus vielen Gründen wirklich schlecht.
HibernateProxy
definiert einewriteReplace
Methode , um Implementierer zu zwingen etwas Besonderes während der Serialisierung zu tun.(T)Hibernate.unproxy(entity)
Wie ich in diesem Artikel erklärt habe , können Sie dies seit Hibernate ORM 5.2.10 folgendermaßen tun:
Vor dem Ruhezustand 5.2.10 . Der einfachste Weg, dies zu tun, war die Verwendung der Unproxy- Methode, die von der internen
PersistenceContext
Implementierung von Hibernate angeboten wird :quelle
Department
mit Liste von habenStudent
, müssen Sie nochunproxy(department.getStudents())
- oder ist es genug, um nurunproxy(department)
?PersistentContext#unproxy(proxy)
wirft eine Ausnahme , wenn der Proxy nicht initialisiert , währendHibernate.unproxy(proxy)
undLazyInitializer#getImplementation(proxy)
initialisieren den Proxy , falls erforderlich. Habe gerade eine Ausnahme wegen dieses Unterschieds gefangen. ;-)Ich habe folgenden Code geschrieben, der das Objekt von Proxys bereinigt (falls diese noch nicht initialisiert sind).
Ich verwende diese Funktion über dem Ergebnis meiner RPC-Dienste (über Aspekte) und bereinigt rekursiv alle Ergebnisobjekte von Proxys (wenn sie nicht initialisiert sind).
quelle
Versuchen zu benutzen
Hibernate.getClass(obj)
quelle
So empfehle ich JPA 2:
quelle
Mit Spring Data JPA und Hibernate habe ich Subschnittstellen von verwendet
JpaRepository
, um Objekte zu suchen, die zu einer Typhierarchie gehören, die mithilfe der "Join" -Strategie zugeordnet wurde. Leider gaben die Abfragen Proxys des Basistyps anstelle von Instanzen der erwarteten konkreten Typen zurück. Dies hinderte mich daran, die Ergebnisse auf die richtigen Typen zu übertragen. Wie Sie bin ich hierher gekommen, um einen effektiven Weg zu finden, um meine Entitäten unberührt zu lassen.Vlad hat die richtige Idee, diese Ergebnisse zu entkräften. Yannis liefert etwas mehr Details. Im Anschluss an ihre Antworten finden Sie hier den Rest von dem, wonach Sie suchen könnten:
Der folgende Code bietet eine einfache Möglichkeit, die Proxy-Funktionen Ihrer Proxy-Entitäten aufzuheben:
Sie können der
unproxy
Methode entweder nicht proxisierte Entitäten oder Proxy-Entitäten übergeben . Wenn sie bereits nicht ordnungsgemäß sind, werden sie einfach zurückgegeben. Andernfalls werden sie nicht entlastet und zurückgegeben.Hoffe das hilft!
quelle
Die andere Problemumgehung besteht darin, anzurufen
Kurz vor dem Schließen der Sitzung.
quelle
Ich habe eine Lösung gefunden, um eine Klasse mithilfe der Standard-Java- und JPA-API zu deproxy. Getestet mit Ruhezustand, erfordert jedoch keinen Ruhezustand als Abhängigkeit und sollte mit allen JPA-Anbietern funktionieren.
Eine einzige Anforderung - es ist erforderlich, die übergeordnete Klasse (Adresse) zu ändern und eine einfache Hilfsmethode hinzuzufügen.
Allgemeine Idee: Fügen Sie der übergeordneten Klasse eine Hilfsmethode hinzu, die sich selbst zurückgibt. Wenn die Methode auf dem Proxy aufgerufen wird, leitet sie den Aufruf an die reale Instanz weiter und gibt diese reale Instanz zurück.
Die Implementierung ist etwas komplexer, da der Ruhezustand erkennt, dass die Proxy-Klasse sich selbst zurückgibt und weiterhin den Proxy anstelle der realen Instanz zurückgibt. Umgehung besteht darin, die zurückgegebene Instanz in eine einfache Wrapper-Klasse zu verpacken, die einen anderen Klassentyp als die reale Instanz hat.
In Code:
Verwenden Sie Folgendes, um den Adressproxy in eine echte Unterklasse umzuwandeln:
quelle
Ab Hiebrnate 5.2.10 können Sie mit der Hibernate.proxy- Methode einen Proxy in Ihre reale Entität konvertieren:
quelle
Vielen Dank für die vorgeschlagenen Lösungen! Leider hat keiner von ihnen für meinen Fall funktioniert: Empfangen einer Liste von CLOB-Objekten aus der Oracle-Datenbank über JPA - Hibernate mithilfe einer nativen Abfrage.
Alle vorgeschlagenen Ansätze gaben mir entweder eine ClassCastException oder gaben nur ein Java-Proxy-Objekt zurück (das tief im Inneren den gewünschten Clob enthielt).
Meine Lösung lautet also wie folgt (basierend auf mehreren oben genannten Ansätzen):
Hoffe das wird jemandem helfen!
quelle