Secciones

Artículos para tus primeros pasos

Si estás empezando a introducirte en el mundo de Groovy y Grails, no te pierdas nuestros artículos básicos: 

Entrevistas con los expertos
 

Los protagonistas te cuentan de qué van los proyectos más importantes del mundo Groovy:


Un proyecto de:
ImaginaWorks
Campus Escuela de Groovy

Grails

Error al grabar un objeto que contiene otro obtenido de la sesion

valmanar - jueves 07/01/2010

Hola a todos, tengo un formulario de login en el cual obtengo el usuario y password, busco estos en la bd y si existe me devuelve un objeto usuario que es el que a encontrado, este objeto lo asigno a la sesion para poderlo utilizar en cualquier formulario. En otro formulario distinto lo obtengo de la sesion para utilizarlo en una clase (Email) ya que es uno de sus atributos, es decir voy a componer un email y el emisor es el objeto que tengo situado en la sesion con el cual se valido el usuario, pues bien al ir a grabar este objeto email  (email.save()) que uno de sus atributos es el objeto usuario comentado anteriormente me lanza la siguiente execpción: org.springframework.orm.hibernate3.HibernateSystemException: a different object with the same identifier value was already associated with the session: [User # 5]; nested exception is org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: [User # 5]

¿Alguien podría ayudarme ó tener idea de por donde van los tiros?

Gracias por la atención.

Re: Error al grabar un objeto que contiene otro obtenido de la sesion

Nacho - viernes 08/01/2010

Hola, el problema es que la sesión de hibernate se cierra cuando termina de procesarse la acción de login, de manera que el objeto usuario que guardas en la sesión web está en estado "detached" y no podrás volverlo a usar en transacciones posteriores.

Mi consejo es que en lugar de guardar el objeto usuario en la sesión guardes únicamente el id, y luego cuando lo necesites de nuevo hagas def u = Usuario.get(session.idUsuario).  De esta manera, guardas menos información en la sesión, con lo que tu aplicación consumirá menos recursos y el servidor tardará menos en los reinicios (recuerda que la sesión se serializa a disco en la mayoría de contenedores de servlets). Además, si tienes activada la caché de segundo nivel de hibernate (que es lo normal y recomendado), recuperar el usuario no siempre producirá una consulta a la base de datos, con lo que la penalización por rendimiento prácticamente no se notará.

 

Saludos,

Re: Error al grabar un objeto que contiene otro obtenido de la sesion

valmanar - lunes 11/01/2010

Hola Nacho, en primer lugar gracia por la respuesta y explicacion, pondré en práctica el consejo aunque me surge una duda y es la siguiente: digamos que en un controler ó una clase hago una consulta de la clase usuario con los métodos dinámicos -> usuario.findAll, esto cargaría todos los usuarios en la caché de hibernate ahora lo que quiero en ese mismo formulario es crear un objeto digamos email y grabarlo el cual una de sus propiedades es una clase usuario, el usuario que se utilize para la propiedad email tiene que ser el que hizo login y su objeto quedó en detached como bien dijiste antes. Está claro que entre todos los objetos usuario en la caché de hibernate está el que quiero utilizar pero al traerlos todos con la consulta no sé "identificar" cuál de ellos hizo login, siguiento tus directrices cargaría con Usuario.get(ssession.idUsuario) (ya que el id si lo dejé guardado en la sesión para cargar el objeto). Si cargo así tendré en la caché el mismo objeto dos veces y podría darme el error que use en el primer mensaje? ó bien comprueba en la caché si tiene el objeto y es este mismo el que me devuelve? si esto es así deduzco que siempre tendría que cargar las consultas "antes" para que luego con el get detecte el objeto en caché, porque si lo hago al revés y cargo antes el objeto y tras esto hago la consulta dentro de la cual uno de los objetos que me devulve es este mismo se me duplicarán en la cache de hibernate y lanzará el:a different object with the same identifier value was already associated with the session.

No sé cual de los dos caminos sería el óptimo ó si estoy equivocado en las apreciaciones, gracias por la atención y los consejos.

Un fuerte saludo 

Responder al hilo | Volver al foro "Grails" | Volver a los foros