Durante una hibernación Session
, estoy cargando algunos objetos y algunos de ellos se cargan como servidores proxy debido a la carga diferida. Todo está bien y no quiero desactivar la carga diferida.
Pero luego necesito enviar algunos de los objetos (en realidad un objeto) al cliente GWT a través de RPC. Y sucede que este objeto concreto es un proxy. Entonces necesito convertirlo en un objeto real. No puedo encontrar un método como "materializar" en Hibernate.
¿Cómo puedo convertir algunos de los objetos de proxies a reales conociendo su clase e ID?
Por el momento, la única solución que veo es desalojar ese objeto del caché de Hibernate y volver a cargarlo, pero es realmente malo por muchas razones.
HibernateProxy
define unwriteReplace
método para obligar a los implementadores a hacer algo especial durante la serialización.(T)Hibernate.unproxy(entity)
Como he explicado en este artículo , ya que Hibernate ORM 5.2.10 , puede hacerlo LiKee esto:
Antes de Hibernate 5.2.10 . La forma más sencilla de hacerlo era utilizar el método no proxy ofrecido por la
PersistenceContext
implementación interna de Hibernate :fuente
Department
Lista deStudent
, ¿todavía necesitaunproxy(department.getStudents())
o es suficienteunproxy(department)
?PersistentContext#unproxy(proxy)
arroja una excepción si el proxy no se inicializaHibernate.unproxy(proxy)
y,LazyInitializer#getImplementation(proxy)
si es necesario, lo inicializa. Acabo de atrapar una excepción debido a esta diferencia. ;-)Tratar de usar
Hibernate.getClass(obj)
fuente
He escrito el siguiente código que limpia el objeto de los servidores proxy (si aún no están inicializados)
Utilizo esta función sobre el resultado de mis servicios RPC (a través de aspectos) y limpia recursivamente todos los objetos de resultados de los servidores proxy (si no están inicializados).
fuente
La forma en que recomiendo con JPA 2:
fuente
Con Spring Data JPA e Hibernate, estaba usando subinterfaces de
JpaRepository
para buscar objetos que pertenecen a una jerarquía de tipos que fue mapeada usando la estrategia de "unión". Desafortunadamente, las consultas estaban devolviendo proxys del tipo base en lugar de instancias de los tipos concretos esperados. Esto me impidió enviar los resultados a los tipos correctos. Al igual que tú, vine aquí buscando una manera efectiva de liberar mis intereses.Vlad tiene la idea correcta para eliminar estos resultados; Yannis proporciona un poco más de detalle. Además de sus respuestas, aquí está el resto de lo que podría estar buscando:
El siguiente código proporciona una manera fácil de desproxiar sus entidades proxy:
Puede pasar entidades no representadas o entidades representadas al
unproxy
método. Si ya no están representados, simplemente serán devueltos. De lo contrario, no serán representados y serán devueltos¡Espero que esto ayude!
fuente
La otra solución es llamar
Justo antes de cerrar la sesión.
fuente
Encontré una solución para desproxiar una clase usando Java estándar y API JPA. Probado con hibernación, pero no requiere hibernación como dependencia y debería funcionar con todos los proveedores de JPA.
Un único requisito: es necesario modificar la clase principal (Dirección) y agregar un método auxiliar simple.
Idea general: agregar un método auxiliar a la clase padre que se devuelve. cuando el método se llama al proxy, reenviará la llamada a la instancia real y devolverá esta instancia real.
La implementación es un poco más compleja, ya que hibernate reconoce que la clase proxy se devuelve a sí misma y aún devuelve proxy en lugar de una instancia real. La solución consiste en ajustar la instancia devuelta en una clase de contenedor simple, que tiene un tipo de clase diferente que la instancia real.
En codigo:
Para enviar el proxy de dirección a una subclase real, use lo siguiente:
fuente
A partir de Hiebrnate 5.2.10 , puede usar el método Hibernate.proxy para convertir un proxy a su entidad real:
fuente
¡Gracias por las soluciones sugeridas! Desafortunadamente, ninguno de ellos funcionó para mi caso: recibir una lista de objetos CLOB de la base de datos Oracle a través de JPA - Hibernate, usando una consulta nativa.
Todos los enfoques propuestos me dieron una ClassCastException o simplemente devolvieron el objeto Proxy java (que contenía profundamente el Clob deseado).
Entonces mi solución es la siguiente (basada en varios enfoques anteriores):
Espero que esto ayude a alguien!
fuente