No se pudo inicializar el proxy – sin sesión

Tengo un error que se ve así:

No se pudo inicializar el proxy – sin sesión

Estoy trabajando con Java, Hibernate y Spring. Este error aparece cuando bash generar un documento PDF, y sigo los siguientes pasos para generarlo sobre la marcha y almacenarlo en la base de datos.

  1. Envié una solicitud a la aplicación a través de un método POST. Esto genera el PDF sobre la marcha y muestra al usuario.

  2. Justo después de esa solicitud, envié otro, pero a través de un ajax una solicitud. Esto generará el mismo PDF pero lo guardará en el DB.

El error muestra que una consulta no se pudo ejecutar debido al error “no se pudo inicializar el servidor proxy – sin sesión”.

¿Hay algo que estoy haciendo mal, llamando a los mismos métodos dos veces desde la misma sesión de usuario? ¿Podría ser que la sesión se cierre antes de que ambas solicitudes hayan terminado?

Espero que alguien pueda ayudarme a entender lo que está sucediendo.

Su problema es que la sesión de hibernación solo vive para una solicitud. Se abre al inicio de la solicitud y se cierra al final. Adivinó la respuesta: la sesión de Hibernate se cierra antes de que ambas solicitudes finalicen.

¿Qué está pasando exactamente? Los objetos de su entidad viven durante ambas solicitudes. ¿Cómo? Se almacenan en la sesión HTTP (que es una cosa diferente llamada sesión) No se proporciona mucha información sobre el marco que está utilizando, por lo que no puedo darle más detalles, pero es cierto que el marco que está utilizando de alguna manera mantiene sus entidades en la sesión HTTP. Así es como el marco le facilita trabajar con los mismos objetos para más de una solicitud.

Cuando se inicia el procesamiento de la segunda solicitud, el código intenta acceder a alguna entidad (normalmente un elemento de una colección) que se hiberna de forma diferida. La entidad no está conectada a una sesión de hibernación, por lo que hibernate no puede inicializar el proxy de hibernación antes de leerlo. Debería abrir una sesión y volver a adjuntar su entidad a ella al comienzo del procesamiento de la solicitud ajax.

EDITAR:

Trataré de dar una breve explicación de lo que está sucediendo detrás de la escena. Todos los marcos web de Java tienen uno o más servlets que manejan las solicitudes. El servlet maneja cada solicitud (HttpRequest) creando un nuevo hilo que finalmente producirá la respuesta (HttpResponse). El método que procesa cada solicitud se ejecuta dentro de este hilo.

Al comienzo del proceso de solicitud, su aplicación debe asignar los recursos que necesita para el procesamiento (transacción, sesión de Hibernación, etc.). Al final del ciclo de procesamiento, estos recursos se liberan (la transacción se confirma, la sesión de hibernación se cierra, las conexiones JDBC se liberan, etc.). El ciclo de vida de estos recursos podría ser administrado por su marco, o podría ser hecho por su código.

Para soportar el estado de la aplicación en un protocolo sin estado como HTTP, tenemos el objeto HttpSession. Nosotros (o los marcos) ponemos en HttpSession la información que sigue siendo relevante entre diferentes ciclos de solicitud del mismo cliente.

Durante el procesamiento de la primera solicitud, hibernate lee (de forma perezosa) una entidad de la base de datos. Debido a la inicialización diferida, algunas partes de la estructura de este objeto son objetos proxy de hibernación. Estos objetos están asociados con la sesión de hibernación que los creó.

El marco encuentra la entidad a partir de la solicitud anterior en el objeto HttpSession cuando intenta procesar la segunda solicitud. Luego está intentando acceder a una propiedad desde una entidad hija que se inicializó de manera lenta y ahora es un objeto proxy de hibernación. El objeto proxy de hibernación es una imitación del objeto real que pedirá a su sesión de hibernación que lo llene con información de la base de datos cuando alguien intente acceder a una de sus propiedades. Esto es lo que su proxy hibernate está tratando de hacer. Pero su sesión se cerró al final del proceso de solicitud anterior, por lo que ahora no tiene una sesión de hibernación para hidratarse (llena de información real).

Tenga en cuenta que es posible que ya haya abierto una sesión de hibernación al comienzo de la segunda solicitud, pero no tiene conocimiento de la entidad que contiene el objeto proxy porque esta entidad fue leída por una sesión de hibernación diferente. Debe volver a conectar la entidad a la nueva sesión de hibernación.

Hay mucha discusión sobre cómo volver a adjuntar una entidad separada, pero el enfoque más simple en este momento es session.update(entity) .

Espero eso ayude.