Pendant une mise en veille prolongée Session
, je charge certains objets et certains d'entre eux sont chargés en tant que proxys en raison d'un chargement paresseux. Tout va bien et je ne veux pas désactiver le chargement paresseux.
Mais plus tard, je dois envoyer certains des objets (en fait un objet) au client GWT via RPC. Et il arrive que cet objet concret soit un proxy. J'ai donc besoin de le transformer en un véritable objet. Je ne trouve pas de méthode comme "matérialiser" dans Hibernate.
Comment puis-je transformer certains objets des proxys en réels en connaissant leur classe et leur ID?
Pour le moment, la seule solution que je vois est d'expulser cet objet du cache d'Hibernate et de le recharger, mais c'est vraiment mauvais pour de nombreuses raisons.
HibernateProxy
Définit également unewriteReplace
méthode pour forcer les implémenteurs à faire quelque chose de spécial pendant la sérialisation.(T)Hibernate.unproxy(entity)
Comme je l'ai expliqué dans cet article , depuis Hibernate ORM 5.2.10 , vous pouvez le faire comme ceci:
Avant Hibernate 5.2.10 . le moyen le plus simple de le faire était d'utiliser la méthode non proxy offerte par l'
PersistenceContext
implémentation interne d'Hibernate :la source
Department
liste avecStudent
, avez-vous toujours besoin deunproxy(department.getStudents())
- ou est-ce suffisantunproxy(department)
?PersistentContext#unproxy(proxy)
lève une exception si le proxy n'est pas initialisé pendantHibernate.unproxy(proxy)
etLazyInitializer#getImplementation(proxy)
initialise le proxy si nécessaire. Juste attrapé une exception en raison de cette différence. ;-)Essayez d'utiliser
Hibernate.getClass(obj)
la source
J'ai écrit le code suivant qui nettoie l'objet des proxies (s'ils ne sont pas déjà initialisés)
J'utilise cette fonction sur le résultat de mes services RPC (via les aspects) et elle nettoie récursivement tous les objets de résultat des proxys (s'ils ne sont pas initialisés).
la source
La façon dont je recommande avec JPA 2:
la source
Avec Spring Data JPA et Hibernate, j'utilisais des sous-interfaces de
JpaRepository
pour rechercher des objets appartenant à une hiérarchie de types mappée à l'aide de la stratégie de «jointure». Malheureusement, les requêtes renvoyaient des proxys du type de base au lieu d'instances des types concrets attendus. Cela m'a empêché de convertir les résultats dans les types appropriés. Comme vous, je suis venu ici à la recherche d'un moyen efficace de me débarrasser de mes émotions.Vlad a la bonne idée pour désintoxiquer ces résultats; Yannis fournit un peu plus de détails. En plus de leurs réponses, voici le reste de ce que vous recherchez peut-être:
Le code suivant fournit un moyen simple de supprimer le proxy de vos entités mandatées:
Vous pouvez transmettre des entités non oxydées ou des entités proxy à la
unproxy
méthode. S'ils sont déjà non corrigés, ils seront simplement renvoyés. Sinon, ils seront sans oxy et retournés.J'espère que cela t'aides!
la source
L'autre solution de contournement consiste à appeler
Juste avant de fermer la session.
la source
J'ai trouvé une solution pour déproxy une classe en utilisant les API Java et JPA standard. Testé avec hibernate, mais ne nécessite pas d'hibernation en tant que dépendance et devrait fonctionner avec tous les fournisseurs JPA.
Une seule exigence - il est nécessaire de modifier la classe parent (Address) et d'ajouter une méthode d'assistance simple.
Idée générale: ajouter une méthode d'assistance à la classe parent qui se retourne. lorsque la méthode est appelée sur le proxy, elle transfère l'appel vers une instance réelle et renvoie cette instance réelle.
La mise en œuvre est un peu plus complexe, car hibernate reconnaît que la classe mandatée se renvoie elle-même et renvoie toujours le proxy au lieu de l'instance réelle. La solution de contournement consiste à envelopper l'instance retournée dans une classe wrapper simple, qui a un type de classe différent de celui de l'instance réelle.
Dans du code:
Pour convertir le proxy d'adresse en sous-classe réelle, utilisez ce qui suit:
la source
À partir de Hiebrnate 5.2.10, vous pouvez utiliser la méthode Hibernate.proxy pour convertir un proxy en votre entité réelle:
la source
Merci pour les solutions proposées! Malheureusement, aucun d'entre eux n'a fonctionné pour mon cas: recevoir une liste d'objets CLOB de la base de données Oracle via JPA - Hibernate, en utilisant une requête native.
Toutes les approches proposées m'ont donné soit une ClassCastException, soit juste un objet proxy java renvoyé (qui contenait profondément à l'intérieur le Clob souhaité).
Ma solution est donc la suivante (basée sur plusieurs approches ci-dessus):
J'espère que cela aidera quelqu'un!
la source