Tengo dos Objetos de usuario y mientras trato de guardar el objeto usando
session.save(userObj);
Estoy teniendo el siguiente error:
Caused by: org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session:
[com.pojo.rtrequests.User#com.pojo.rtrequests.User@d079b40b]
Estoy creando la sesión usando
BaseHibernateDAO dao = new BaseHibernateDAO();
rtsession = dao.getSession(userData.getRegion(),
BaseHibernateDAO.RTREQUESTS_DATABASE_NAME);
rttrans = rtsession.beginTransaction();
rttrans.begin();
rtsession.save(userObj1);
rtsession.save(userObj2);
rtsession.flush();
rttrans.commit();
rtsession.close(); // in finally block
También intenté hacer lo session.clear()
antes de guardar, todavía sin suerte.
Esta es la primera vez que obtengo el objeto de sesión cuando llega una solicitud de usuario, así que entiendo por qué dice que el objeto está presente en la sesión.
¿Alguna sugerencia?
Respuestas:
He tenido este error muchas veces y puede ser bastante difícil de localizar ...
Básicamente, lo que hibernate está diciendo es que tienes dos objetos que tienen el mismo identificador (la misma clave primaria) pero no son el mismo objeto.
Le sugiero que analice su código, es decir, comente los bits hasta que desaparezca el error y luego vuelva a colocar el código hasta que vuelva y encuentre el error.
La mayoría de las veces ocurre a través de guardados en cascada donde hay un guardado en cascada entre el objeto A y B, pero el objeto B ya se ha asociado con la sesión pero no está en la misma instancia de B que el de A.
¿Qué generador de claves primarias estás usando?
La razón por la que pregunto es que este error está relacionado con cómo le está diciendo a Hibernate que determine el estado persistente de un objeto (es decir, si un objeto es persistente o no). El error podría estar ocurriendo porque hibernate está tratando de persistir un objeto que ya es persistente. De hecho, si usa save hibernate intentará persistir ese objeto, y tal vez ya exista un objeto con esa misma clave primaria asociada con la sesión.
Ejemplo
Suponiendo que tiene un objeto de clase de hibernación para una tabla con 10 filas basadas en una combinación de clave principal (columna 1 y columna 2). Ahora, ha eliminado 5 filas de la tabla en algún momento. Ahora, si intenta agregar las mismas 10 filas nuevamente, mientras hibernate intenta persistir los objetos en la base de datos, se agregarán 5 filas que ya fueron eliminadas sin errores. Ahora, las 5 filas restantes que ya existen, lanzarán esta excepción.
Entonces, el enfoque fácil sería verificar si ha actualizado / eliminado algún valor en una tabla que es parte de algo y luego está tratando de insertar los mismos objetos nuevamente
fuente
Este es solo un punto en el que la hibernación crea más problemas de los que resuelve. En mi caso hay muchos objetos con el mismo identificador 0, porque son nuevos y no tienen uno. La base de datos los genera. En algún lugar he leído que las señales 0 no están configuradas. La forma intuitiva de mantenerlos es iterar sobre ellos y decir hibernar para guardar los objetos. Pero no puedes hacer eso - "Por supuesto que debes saber que la hibernación funciona de esta y de esa manera, por lo tanto tienes que ..." Así que ahora puedo intentar cambiar los ID a Long en lugar de long y ver si funciona. Al final, es más fácil hacerlo con un simple mapeador por su cuenta, porque la hibernación es solo una carga intransparente adicional. Otro ejemplo: intentar leer los parámetros de una base de datos y conservarlos en otra le obliga a hacer casi todo el trabajo manualmente.
fuente
UTILIZAR
session.evict(object);
La función deevict()
método se utiliza para eliminar la instancia de la caché de sesión. Entonces, por primera vez al guardar el objeto, guarde el objeto llamando alsession.save(object)
método antes de desalojar el objeto de la caché. De la misma manera, actualice el objeto llamandosession.saveOrUpdate(object)
osession.update(object)
antes de llamar a evict ().fuente
Esto puede suceder cuando ha utilizado el mismo objeto de sesión para lectura y escritura. ¿Cómo? Digamos que ha creado una sesión. Ha leído un registro de la tabla de empleados con la clave primaria Emp_id = 101 Ahora ha modificado el registro en Java. Y va a guardar el registro del empleado en la base de datos. no hemos cerrado sesión en ningún lugar aquí. Como el objeto que se leyó también persiste en la sesión. Entra en conflicto con el objeto que deseamos escribir. De ahí viene este error.
fuente
Como alguien ya señaló anteriormente, me encontré con este problema cuando tenía
cascade=all
en ambos extremos de unaone-to-many
relación, así que supongamos A -> B (uno a muchos de A y muchos a uno de B) y estaba actualizando la instancia de B en A y luego llamando a saveOrUpdate (A), resultó en una solicitud de guardado circular, es decir, guardar de A desencadena guardar de B que desencadena guardar de A ... y en la tercera instancia cuando se intentó la entidad (de A) Al agregarse al sessionPersistenceContext, se lanzó la excepción duplicateObject.Podría resolverlo quitando la cascada de un extremo.
fuente
Puede usar
session.merge(obj)
, si está guardando con diferentes sesiones con el mismo identificador de objeto persistente.Funcionó, tuve el mismo problema antes.
fuente
También encontré este problema y me costó encontrar el error.
El problema que tuve fue el siguiente:
El objeto ha sido leído por un Dao con una sesión de hibernación diferente.
Para evitar esta excepción, simplemente vuelva a leer el objeto con el dao que guardará / actualizará este objeto más adelante.
entonces:
¡Espero que algunas personas ahorren mucho tiempo!
fuente
Me encontré con este problema por:
Lo resolví vaciando los resultados después de la eliminación y borrando el caché antes de guardar el nuevo objeto
fuente
Este problema ocurre cuando actualizamos el mismo objeto de sesión, que hemos utilizado para buscar el objeto de la base de datos.
Puede utilizar el método de fusión de hibernación en lugar del método de actualización.
Por ejemplo, primero use session.get () y luego puede usar session.merge (object). Este método no creará ningún problema. También podemos usar el método merge () para actualizar el objeto en la base de datos.
fuente
Obtenga el objeto dentro de la sesión, aquí un ejemplo:
fuente
¿Son correctas sus asignaciones de identificación? Si la base de datos es responsable de crear el Id a través de un identificador, debe asignar su objeto de usuario a eso.
fuente
Encontré este problema al eliminar un objeto, ni el desalojo ni el borrado ayudaron.
fuente
antes de la posición donde comienzan los objetos repetitivos, debe cerrar la sesión y luego debe comenzar una nueva sesión
por lo que de esta forma en una sesión no hay más de una entidad que tenga el mismo identificador.
fuente
Llega tarde a la fiesta, pero puede ayudar a los futuros usuarios.
Tengo este problema cuando selecciono un registro usando
getsession()
y nuevamente actualizo otro registro con el mismo identificador usando la misma sesión que causa el problema. Código agregado a continuación.Esto nunca debería hacerse. La solución es desalojar la sesión antes de actualizar o cambiar la lógica empresarial.
fuente
Compruebe si olvidó poner @GenerateValue para la columna @Id. Tuve el mismo problema con la relación de muchos a muchos entre Película y Género. El programa arrojó Hibernate Error: org.hibernate.NonUniqueObjectException: un objeto diferente con el mismo valor de identificador ya estaba asociado con el error de sesión. Más tarde descubrí que solo tengo que asegurarme de que tienes @GenerateValue en el método de obtención de GenreId.
fuente
solo verifique la identificación si toma nulo o 0 como
en agregar o actualizar donde el contenido se establece de formulario a Pojo
fuente
Soy nuevo en NHibernate, y mi problema fue que usé una sesión diferente para consultar mi objeto que la que usé para guardarlo. Entonces, la sesión de ahorro no sabía sobre el objeto.
Parece obvio, pero al leer las respuestas anteriores, estaba buscando 2 objetos en todas partes, no 2 sesiones.
fuente
@GeneratedValue (estrategia = GenerationType.IDENTITY), agregar esta anotación a la propiedad de clave primaria en su bean de entidad debería resolver este problema.
fuente
Resolví este problema.
En realidad, esto está sucediendo porque olvidamos la implementación del tipo de generador de la propiedad PK en la clase bean. Así que hazlo de cualquier tipo como
cuando persistimos los objetos de bean, cada objeto adquirió la misma ID, por lo que el primer objeto se guarda, cuando otro objeto persiste, luego HIB FW a través de este tipo de
Exception: org.hibernate.NonUniqueObjectException:
un objeto diferente con el mismo valor de identificador ya estaba asociado con la sesión.fuente
El problema ocurre porque en la misma sesión de hibernación está tratando de guardar dos objetos con el mismo identificador. Hay dos soluciones: -
Esto sucede porque no ha configurado su archivo mapping.xml correctamente para los campos de identificación como se muestra a continuación:
Sobrecargue el método getsession para aceptar un parámetro como isSessionClear y borre la sesión antes de devolver la sesión actual como se muestra a continuación
Esto hará que los objetos de sesión existentes se borren e incluso si hibernación no genera un identificador único, suponiendo que haya configurado su base de datos correctamente para una clave primaria usando algo como Auto_Increment, debería funcionar para usted.
fuente
Tuve un problema similar. En mi caso, me había olvidado de establecer el
increment_by
valor en la base de datos para que fuera el mismo que el utilizado porcache_size
yallocationSize
. (Las flechas apuntan a los atributos mencionados)SQL:
Java:
fuente
De lo contrario a lo que dijo wbdarby , incluso puede suceder cuando se busca un objeto dando el identificador del objeto a un HQL. En el caso de intentar modificar los campos del objeto y guardarlo nuevamente en la base de datos (la modificación podría ser insertar, eliminar o actualizar) en la misma sesión , aparecerá este error. Intente borrar la sesión de hibernación antes de guardar su objeto modificado o cree una nueva sesión.
Espero haber ayudado ;-)
fuente
Tengo el mismo error que estaba reemplazando mi Set con uno nuevo de Jackson.
Para resolver esto, mantengo el conjunto existente, elimino del conjunto antiguo el elemento desconocido en la nueva lista con
retainAll
. Luego agrego los nuevos conaddAll
.No es necesario tener la sesión y manipularla.
fuente
Prueba esto. ¡Lo siguiente funcionó para mí!
En el
hbm.xml
archivoNecesitamos establecer el
dynamic-update
atributo de la etiqueta de clase entrue
:Establezca el atributo de clase de la etiqueta del generador en la columna única en
identity
:Nota: establezca la columna única en en
identity
lugar deassigned
.fuente
Otra cosa que funcionó para mí fue hacer que la variable de instancia Long en lugar de long
Tenía mi identificación larga de la variable de clave principal; cambiarlo a Long id; trabajó
Todo lo mejor
fuente
Siempre puedes hacer una descarga de sesión. Flush sincronizará el estado de todos sus objetos en sesión (por favor, alguien me corrija si me equivoco), y tal vez resuelva su problema en algunos casos.
La implementación de sus propios iguales y código hash también puede ayudarlo.
fuente
Puede comprobar su configuración de cascada. La configuración de Cascade en sus modelos podría estar causando esto. Eliminé la configuración de cascada (esencialmente no permite las inserciones / actualizaciones de cascada) y esto resolvió mi problema
fuente
También encontré este error. Lo que funcionó para mí es asegurarme de que la clave principal (que se genera automáticamente) no sea un PDT (es decir, largo, int, ect.), Sino un objeto (es decir, Long, Integer, etc.)
Cuando cree su objeto para guardarlo, asegúrese de pasar nulo y no 0.
fuente
¿Esto ayuda?
fuente
He resuelto un problema similar como ese:
fuente