Me aparece el siguiente error de hibernación. Puedo identificar la función que causa el problema. Lamentablemente, hay varias llamadas de DB en la función. No puedo encontrar la línea que causa el problema ya que hibernate limpia la sesión al final de la transacción. El error de hibernación mencionado a continuación parece un error general. Ni siquiera mencionó qué Bean causa el problema. ¿Alguien familiarizado con este error de hibernación?
org.hibernate.StaleStateException: Batch update returned unexpected row count from update: 0 actual row count: 0 expected: 1
at org.hibernate.jdbc.BatchingBatcher.checkRowCount(BatchingBatcher.java:93)
at org.hibernate.jdbc.BatchingBatcher.checkRowCounts(BatchingBatcher.java:79)
at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:58)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:195)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:235)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:142)
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:297)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:985)
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:333)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
at org.springframework.orm.hibernate3.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:584)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransacti
onManager.java:500)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManag
er.java:473)
at org.springframework.transaction.interceptor.TransactionAspectSupport.doCommitTransactionAfterReturning(Transaction
AspectSupport.java:267)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:106)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:170)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:176)
Respuestas:
Sin el código y las asignaciones para sus transacciones, será casi imposible investigar el problema.
Sin embargo, para comprender mejor qué causa el problema, intente lo siguiente:
Espero que ayude.
fuente
Obtuve la misma excepción al eliminar un registro por Id que no existe en absoluto. Así que verifique que el registro que está actualizando / eliminando realmente exista en DB
fuente
Solución: en el archivo de mapeo Hibernate para la propiedad id, si usa cualquier clase de generador, para esa propiedad no debe establecer el valor explícitamente utilizando un método setter.
Si establece el valor de la propiedad Id explícitamente, generará el error anterior. Marque esto para evitar este error. o Se muestra un error cuando menciona en el archivo de mapeo el campo generador = "nativo" o "incremental" y en su BASE DE DATOS la tabla asignada no está auto_incrementada Solución: vaya a su BASE DE DATOS y actualice su tabla para configurar auto_increment
fuente
Esto me sucedió una vez por accidente cuando estaba asignando ID específicos a algunos objetos (pruebas) y luego intentaba guardarlos en la base de datos. El problema era que en la base de datos había una política específica para configurar las ID de los objetos. Simplemente no asigne una identificación si tiene una política a nivel de Hibernate.
fuente
En mi caso, llegué a esta excepción en dos casos similares:
@Transactional
, tuve una llamada a otro servicio (con largos tiempos de respuesta). El método actualiza algunas propiedades de la entidad (después del método, la entidad todavía existe en la base de datos). Si el usuario solicita dos veces el método (ya que piensa que no funciona la primera vez) al salir del método transaccional la segunda vez, Hibernate intenta actualizar una entidad que ya cambió su estado desde el comienzo de la transacción. A medida que Hibernate busca una entidad en un estado y encuentra la misma entidad pero que ya cambió con la primera solicitud, arroja una excepción ya que no puede actualizar la entidad. Es como un conflicto en GIT.Conclusión: en mi caso, no fue un problema que se puede encontrar en el código. Esta excepción se produce cuando Hibernate descubre que la entidad obtenida por primera vez de la base de datos cambió durante la transacción actual , por lo que no puede vaciarla a la base de datos ya que Hibernate no sabe cuál es la versión correcta de la entidad: la actual búsqueda de transacciones al principio; o el que ya está almacenado en la base de datos.
Solución: para resolver el problema, tendrá que jugar con Hibernate LockMode para encontrar el que mejor se adapte a sus necesidades.
fuente
LockMode.READ
oLockMode.OPTIMISTIC
.Acabo de encontrar este problema y descubrí que estaba eliminando un registro e intentando actualizarlo luego en una transacción de Hibernate.
fuente
Esto puede suceder cuando los desencadenantes ejecutan consultas DML (modificación de datos) adicionales que afectan los recuentos de filas. Mi solución fue agregar lo siguiente en la parte superior de mi disparador:
fuente
Estaba enfrentando el mismo problema. El código funcionaba en el entorno de prueba. Pero no estaba funcionando en un entorno de ensayo.
El problema era que la tabla tenía una sola entrada para cada clave primaria en la prueba de la tabla DB. Pero en la puesta en escena DB había múltiples entradas para la misma clave primaria. (El problema está en la puesta en escena de la base de datos, la tabla no tenía restricciones de clave principal y también había entradas múltiples).
Entonces, cada vez que se realiza una operación de actualización, falla. Intenta actualizar un solo registro y espera obtener el recuento de actualizaciones como 1. Pero como había 3 registros en la tabla para la misma clave primaria, el recuento de actualizaciones de resultados encuentra 3. Dado que el recuento de actualizaciones esperado y el recuento de actualizaciones de resultados reales no coinciden , Lanza excepción y retrocede.
Después de que eliminé todos los registros que tienen clave principal duplicada y agregué restricciones de clave principal. Esta funcionando bien
recuento de filas real: 0 // significa que no se encontró ningún registro para actualizar la
actualización: 0 // significa que no se encontró ningún registro, por lo que no se
espera ninguna actualización : 1 // significa que se espera al menos 1 registro con clave en la tabla db.
Aquí el problema es que la consulta intenta actualizar un registro para alguna clave, pero hibernate no encontró ningún registro con la clave.
fuente
Como dice Julius , esto sucede cuando ocurre una actualización en un objeto que tiene sus hijos eliminados. (Probablemente porque se necesitaba una actualización para todo el objeto Padre y, a veces, preferimos eliminar los hijos y volver a insertarlos en el Padre (lo nuevo, lo viejo no importa) junto con cualquier otra actualización que el padre pueda tener en cualquiera de sus otros campos simples) Entonces ... para que esto funcione, elimine los elementos secundarios (dentro de una transacción) llamando al lado del objeto padre. Luego actualice el padre (fatherDAO.update (father)). (Repita para cada objeto padre) El resultado es que los niños tienen su vínculo con su padre despojado y luego el marco los elimina como huérfanos.
childrenList.clear()
(No recorra los elementos secundarios y elimine cada uno con algunoschildDAO.delete(childrenList.get(i).delete()))
y establezca@OneToMany(cascade = CascadeType.XXX ,orphanRemoval=true)
fuente
Encontré este problema donde teníamos una relación de muchos.
En el archivo de mapeo hbnate hbm para master, para objeto con arreglo de tipo de conjunto, se agregó
cascade="save-update"
y funcionó bien.Sin esto, por defecto hibernate intenta actualizar para un registro inexistente y al hacerlo se inserta en su lugar.
fuente
También puede suceder cuando intentas
UPDATE
una CLAVE PRIMARIA .fuente
Tengo el mismo problema y verifiqué que esto puede ocurrir debido a la clave primaria de incremento automático. Para resolver este problema, no inserte el valor de incremento automático con el conjunto de datos. Insertar datos sin la clave primaria.
fuente
Otra forma de obtener este error es si tiene un elemento nulo en una colección.
fuente
sucede cuando intentas eliminar el mismo objeto y luego vuelves a actualizar el mismo objeto, usa esto después de eliminar
session.clear ();
fuente
Esto también me sucedió a mí, porque tenía mi ID como Long, y estaba recibiendo de la vista el valor 0, y cuando intenté guardar en la base de datos recibí este error, luego lo arreglé estableciendo el ID en nulo.
fuente
Me encontré con este problema cuando comenzaba manualmente y confirmaba transacciones dentro del método anotado como
@Transactional
. Solucioné el problema al detectar si ya existía una transacción activa.Luego permití que Spring manejara la confirmación de la transacción.
fuente
Esto sucede cuando declaraste el JSF Managed Bean como
cuando deberías declarar como
Saludos;
fuente
Recibí este error cuando intenté actualizar un objeto con una identificación que no existía en la base de datos. La razón de mi error fue que había asignado manualmente una propiedad con el nombre 'id' a la representación JSON del lado del cliente del objeto y luego, al deserializar el objeto en el lado del servidor, esta propiedad 'id' sobrescribiría la variable de instancia ( también llamado 'id') que se suponía que Hibernate debía generar. Por lo tanto, tenga cuidado al nombrar colisiones si está utilizando Hibernate para generar identificadores.
fuente
También me encontré con el mismo desafío. En mi caso, estaba actualizando un objeto que ni siquiera existía, usando
hibernateTemplate
.En realidad, en mi aplicación estaba obteniendo un objeto DB para actualizar. Y mientras actualizaba sus valores, también actualicé su ID por error, y seguí actualizándolo y encontré dicho error.
Estoy usando
hibernateTemplate
para operaciones CRUD.fuente
Después de leer todas las respuestas, no encontré a nadie para hablar sobre el atributo inverso de hibernación.
En mi opinión, también debe verificar en su mapeo de relaciones si la palabra clave inversa está configurada adecuadamente. Inverso palabra clave se crea para definir de qué lado es el propietario para mantener la relación. El procedimiento para actualizar e insertar varía según este atributo.
Supongamos que tenemos dos tablas:
principal_table , middle_table
con una relación de uno a muchos . Las clases de mapeo de hibernación son Principal y Medio, respectivamente.
Entonces, la clase Principal tiene un SET de objetos intermedios . El archivo de mapeo xml debería ser como sigue:
Como inverso se establece en "verdadero", significa que la clase "Media" es el propietario de la relación, por lo que la clase Principal NO ACTUALIZARÁ la relación.
Entonces, el procedimiento de actualización podría implementarse así:
Esto funcionó para mí, pero puede sugerir algunas ediciones para mejorar la solución. De esa manera todos estaremos aprendiendo.
fuente
En nuestro caso, finalmente descubrimos la causa raíz de StaleStateException.
De hecho, estábamos eliminando la fila dos veces en una sola sesión de hibernación. Anteriormente estábamos usando ojdbc6 lib, y esto estaba bien en esta versión.
Pero cuando actualizamos a odjc7 u ojdbc8, eliminar registros dos veces arrojaba una excepción. Hubo un error en nuestro código donde estábamos borrando dos veces, pero eso no era evidente en ojdbc6.
Pudimos reproducir con este código:
En la primera descarga hibernate va y realiza cambios en la base de datos. Durante la segunda descarga, hibernate compara el objeto de la sesión con el registro de la tabla real, pero no pudo encontrar uno, de ahí la excepción.
fuente
Este problema se produce principalmente cuando estamos tratando de guardar o actualizar el objeto que ya está siendo recuperado en la memoria por una sesión en ejecución. Si ha obtenido un objeto de la sesión y está intentando actualizar en la base de datos, se puede generar esta excepción.
Usé session.evict (); para eliminar primero el caché almacenado en hibernación o si no quiere arriesgarse a perder datos, mejor haga otro objeto para almacenar la temperatura de datos.
fuente
Problema de Hibernate 5.4.1 y HHH-12878
Antes de Hibernate 5.4.1, las excepciones optimistas de falla de bloqueo (por ejemplo,
StaleStateException
oOptimisticLockException
) no incluían la declaración de falla.El problema HHH-12878 se creó para mejorar Hibernate de modo que cuando se lanza una excepción de bloqueo optimista, la
PreparedStatement
implementación de JDBC también se registra:Tiempo de prueba
Primero, definiremos una
Post
entidad que defina una@Version
propiedad, permitiendo así el mecanismo de bloqueo optimista implícito :Habilitaremos el procesamiento por lotes JDBC utilizando las siguientes 3 propiedades de configuración:
Vamos a crear 3
Post
entidades:E Hibernate ejecutará una inserción por lotes JDBC:
Entonces, sabemos que el procesamiento por lotes JDBC funciona bien.
Ahora, repliquemos el problema optimista de bloqueo:
La primera transacción selecciona todas las
Post
entidades y modifica lastitle
propiedades.Sin embargo, antes de que
EntityManager
se vacíe el primero , vamos a ejecutar una segunda transición utilizando elexecuteSync
método.La segunda transacción modifica la primera
Post
, porversion
lo que se incrementará:Ahora, cuando la primera transacción intente vaciar el
EntityManager
, obtendremos elOptimisticLockException
:Por lo tanto, debe actualizar a Hibernate 5.4.1 o posterior para beneficiarse de esta mejora.
fuente
Esto sucedió si cambia algo en el conjunto de datos utilizando una consulta SQL nativa pero el objeto persistente para el mismo conjunto de datos está presente en la caché de la sesión. Use session.evict (yourObject);
fuente
Hibernate almacena en caché los objetos de la sesión. Si el objeto es accedido y modificado por más de 1 usuario,
org.hibernate.StaleStateException
puede ser arrojado. Se puede resolver con el método de fusión / actualización de entidad antes de guardar o usar el bloqueo. Más información: http://java-fp.blogspot.lt/2011/09/orghibernatestalestateexception-batch.htmlfuente
Uno de los casos
fuente
Estaba enfrentando esta excepción, e hibernate estaba funcionando bien. Traté de insertar manualmente un registro usando pgAdmin, aquí el problema quedó claro. La consulta de inserción SQL devuelve 0 inserción. y hay una función desencadenante que causa este problema porque devuelve nulo. así que solo tengo que configurarlo para que regrese nuevo. Y finalmente resolví el problema.
Espero que ayude a cualquier cuerpo.
fuente
Recibí este error porque mapeé la
ID
columna por error usandoId(x => x.Id, "id").GeneratedBy.**Assigned**();
Problema resuelto usando
Id(x => x.Id, "id").GeneratedBy.**Identity**();
fuente
Esto me sucede porque me falta la declaración de ID en la clase de bean.
fuente
En mi caso, hubo un problema con la base de datos, ya que uno de los Procs almacenados estaba consumiendo toda la CPU causando tiempos de respuesta DB altos. Una vez que esto fue asesinado, el problema se resolvió.
fuente