So konvertieren Sie einen Hibernate-Proxy in ein echtes Entitätsobjekt
Lesezeit: 5 Minuten
Andrej Minogin
Während eines Winterschlafs Session, ich lade einige Objekte und einige von ihnen werden aufgrund von verzögertem Laden als Proxys geladen. Es ist alles in Ordnung und ich möchte Lazy Loading 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 es in ein echtes Objekt verwandeln. Ich kann in Hibernate keine Methode wie “materialisieren” finden.
Wie kann ich einige der Objekte von Proxys in Reals umwandeln, wenn ich ihre Klasse und ID kenne?
Im Moment sehe ich 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.
Bozo
Hier ist eine Methode, die ich verwende.
public static <T> T initializeAndUnproxy(T entity) {
if (entity == null) {
throw new
NullPointerException("Entity passed for initialization is null");
}
Hibernate.initialize(entity);
if (entity instanceof HibernateProxy) {
entity = (T) ((HibernateProxy) entity).getHibernateLazyInitializer()
.getImplementation();
}
return entity;
}
Ich wollte dasselbe tun, also habe ich die Proxy-Instanz in einen ObjectOutputStream geschrieben und sie dann von einem entsprechenden ObjectInputStream zurückgelesen, und das schien zu funktionieren. Ich bin mir nicht sicher, ob es ein effizienter Ansatz ist, aber ich frage mich immer noch, warum es funktioniert hat … alle Kommentare dazu werden sehr geschätzt. Danke!
– Shrin1000
8. März 2011 um 11:41 Uhr
@ shrini1000 es hat funktioniert, weil beim Serialisieren die Sammlung initialisiert wird (wenn die Sitzung noch nicht geschlossen ist). Ebenfalls HibernateProxy definiert a writeReplace Methode, um Implementierer zu zwingen, während der Serialisierung etwas Besonderes zu tun.
– Bozo
8. März 2011 um 11:46 Uhr
Gibt es eine portable (JPA) Möglichkeit, dies zu tun?
– Kawu
7. Januar 2012 um 15:19 Uhr
Warum wirft Hibernate.initialize lazyInitializeException, wenn ich es aufrufe? Im nur mit wie: Object o = session.get(MyClass.class, id); Objekt other = o.getSomeOtherClass(); initializeAndUnproxy (andere);
– fredcrs
31. Januar 2012 um 10:26 Uhr
Sie können dasselbe ohne Ihre eigene util-Klasse tun – (T)Hibernate.unproxy(entity)
Vor dem Winterschlaf 5.2.10. Der einfachste Weg, dies zu tun, war die Verwendung von unproxy Methode, die von Hibernate intern angeboten wird PersistenceContext Implementierung:
Behandelt der Aufruf dieser Funktion bei einer übergeordneten Entität Sammlungsfelder? zB wenn Sie eine haben Department mit Liste von Studentmusst du noch unproxy(department.getStudents()) – oder reicht es einfach unproxy(department)?
– trafalmadorianisch
28. November 2019 um 4:01 Uhr
Nur der angegebene Proxy wird initialisiert. Es wird nicht an Assoziationen kaskadiert, da dies möglicherweise Tonnen von Daten laden könnte, wenn Sie zufällig eine Root-Entität entproxyn.
– Vlad Mihalcea
28. November 2019 um 4:15 Uhr
aber PersistentContext#unproxy(proxy) löst eine Ausnahme aus, wenn der Proxy währenddessen nicht initialisiert ist Hibernate.unproxy(proxy) und LazyInitializer#getImplementation(proxy) Initialisieren Sie ggf. den Proxy. Aufgrund dieses Unterschieds wurde gerade eine Ausnahme abgefangen. 😉
– bgraves
3. Mai 2020 um 13:25 Uhr
Sanek Shu
Versuchen zu benutzen Hibernate.getClass(obj)
Dies gibt die Klasse und nicht das entproxyte Objekt selbst zurück
– Stefan Haberl
20. Juni 2013 um 21:53 Uhr
Eigentlich ist diese Lösung großartig, wenn wir versuchen, die Klasse von obj für Instanzen von Vergleichen zu finden.
– João Rebelo
30. Oktober 2018 um 11:12 Uhr
Beachten Sie, dass das Javadoc besagt: “Diese Operation initialisiert einen Proxy durch Nebeneffekt.”
– snorbi
20. Februar um 15:11 Uhr
Sergej Bondarew
Ich habe folgenden Code geschrieben, der das Objekt von Proxys bereinigt (falls sie nicht bereits initialisiert sind)
Ich verwende diese Funktion über das Ergebnis meiner RPC-Dienste (über Aspekte) und sie reinigt rekursiv alle Ergebnisobjekte von Proxys (wenn sie nicht initialisiert sind).
Ich habe diese Lösung ausprobiert … funktioniert nicht immer, wenn Sie nicht so etwas vor den Unwrap-Befehl setzen: HibernateProxy hibernateProxy = (HibernateProxy)possibleProxyObject; Wenn (hibernateProxy.getHibernateLazyInitializer().isUninitialized()){ hibernateProxy.getHibernateLazyInitializer().initialize(); }
Ich habe diese Lösung ausprobiert … funktioniert nicht immer, wenn Sie nicht so etwas vor den Unwrap-Befehl setzen: HibernateProxy hibernateProxy = (HibernateProxy)possibleProxyObject; Wenn (hibernateProxy.getHibernateLazyInitializer().isUninitialized()){ hibernateProxy.getHibernateLazyInitializer().initialize(); }
– Benutzer3227576
7. Februar 2017 um 11:12 Uhr
0x6B6F77616C74
Die andere Problemumgehung besteht darin, anzurufen