org.hibernate.StaleStateException:批量更新从update 返回意外的行数; 实际行数:0; 预期

当我尝试从spring mvc应用程序更新数据库中的值时,我收到此错误:

org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1 at org.hibernate.jdbc.Expectations$BasicExpectation.checkBatched(Expectations.java:61) at org.hibernate.jdbc.Expectations$BasicExpectation.verifyOutcome(Expectations.java:46) at org.hibernate.jdbc.BatchingBatcher.checkRowCounts(BatchingBatcher.java:68) at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:48) at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:242) at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:235) at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:140) at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298) at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27) at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000) at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:338) at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106) at org.springframework.orm.hibernate3.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:656) at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:754) at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:723) at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:393) at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:120) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172) at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202) at com.sun.proxy.$Proxy21.updatePerson(Unknown Source) at se.lowdin.civilforsvaret.webapp.controller.EditPersonContoller.save(EditPersonContoller.java:57) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:601) at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:176) at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:426) at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:414) at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:790) at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:719) at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:644) at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:560) at javax.servlet.http.HttpServlet.service(HttpServlet.java:641) at javax.servlet.http.HttpServlet.service(HttpServlet.java:722) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:304) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:240) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:164) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:462) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100) at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:562) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:395) at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:250) at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:188) at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:166) at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:302) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) at java.lang.Thread.run(Thread.java:722) DEBUG: org.hibernate.jdbc.AbstractBatcher - about to close PreparedStatement (open PreparedStatements: 1, globally: 1) TRACE: org.hibernate.jdbc.AbstractBatcher - closing statement ERROR: org.hibernate.event.def.AbstractFlushingEventListener - Could not synchronize database state with session org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1 at org.hibernate.jdbc.Expectations$BasicExpectation.checkBatched(Expectations.java:61) at org.hibernate.jdbc.Expectations$BasicExpectation.verifyOutcome(Expectations.java:46) at org.hibernate.jdbc.BatchingBatcher.checkRowCounts(BatchingBatcher.java:68) at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:48) at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:242) at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:235) at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:140) at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298) at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27) at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000) at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:338) at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106) at org.springframework.orm.hibernate3.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:656) at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:754) at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:723) at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:393) at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:120) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172) at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202) at com.sun.proxy.$Proxy21.updatePerson(Unknown Source) at se.lowdin.civilforsvaret.webapp.controller.EditPersonContoller.save(EditPersonContoller.java:57) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:601) at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:176) at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:426) at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:414) at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:790) at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:719) at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:644) at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:560) at javax.servlet.http.HttpServlet.service(HttpServlet.java:641) at javax.servlet.http.HttpServlet.service(HttpServlet.java:722) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:304) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:240) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:164) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:462) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100) at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:562) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:395) at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:250) at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:188) at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:166) at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:302) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) at java.lang.Thread.run(Thread.java:722) TRACE: org.hibernate.jdbc.ConnectionManager - registering flush end DEBUG: org.hibernate.transaction.JDBCTransaction - rollback DEBUG: org.hibernate.transaction.JDBCTransaction - re-enabling autocommit DEBUG: org.hibernate.transaction.JDBCTransaction - rolled back JDBC Connection TRACE: org.hibernate.jdbc.JDBCContext - after transaction completion DEBUG: org.hibernate.jdbc.ConnectionManager - transaction completed on session with on_close connection release mode; be sure to close the session to release JDBC resources! TRACE: org.hibernate.impl.SessionImpl - after transaction completion TRACE: org.hibernate.impl.SessionImpl - closing session TRACE: org.hibernate.jdbc.ConnectionManager - performing cleanup DEBUG: org.hibernate.jdbc.ConnectionManager - releasing JDBC connection [ (open PreparedStatements: 0, globally: 0) (open ResultSets: 0, globally: 0)] TRACE: org.hibernate.jdbc.JDBCContext - after transaction completion DEBUG: org.hibernate.jdbc.ConnectionManager - transaction completed on session with on_close connection release mode; be sure to close the session to release JDBC resources! TRACE: org.hibernate.impl.SessionImpl - after transaction completion feb 07, 2014 11:04:32 FM org.apache.catalina.core.StandardWrapperValve invoke SEVERE: Servlet.service() for servlet [spring] in context with path [/CRUDWebAppMavenized] threw exception [Request processing failed; nested exception is org.springframework.orm.hibernate3.HibernateOptimisticLockingFailureException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1; nested exception is org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1] with root cause org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1 at org.hibernate.jdbc.Expectations$BasicExpectation.checkBatched(Expectations.java:61) at org.hibernate.jdbc.Expectations$BasicExpectation.verifyOutcome(Expectations.java:46) at org.hibernate.jdbc.BatchingBatcher.checkRowCounts(BatchingBatcher.java:68) at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:48) at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:242) at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:235) at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:140) at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298) at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27) at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000) at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:338) at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106) at org.springframework.orm.hibernate3.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:656) at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:754) at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:723) at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:393) at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:120) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172) at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202) at com.sun.proxy.$Proxy21.updatePerson(Unknown Source) at se.lowdin.civilforsvaret.webapp.controller.EditPersonContoller.save(EditPersonContoller.java:57) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:601) at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:176) at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:426) at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:414) at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:790) at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:719) at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:644) at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:560) at javax.servlet.http.HttpServlet.service(HttpServlet.java:641) at javax.servlet.http.HttpServlet.service(HttpServlet.java:722) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:304) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:240) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:164) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:462) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100) at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:562) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:395) at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:250) at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:188) at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:166) at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:302) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) at java.lang.Thread.run(Thread.java:722) 

所以我的实际错误似乎与数据库中的ID有关,并且有什么更新。 在我的GET方法中,我得到的是当前ID,在这种情况下是10。

 @Autowired PersonService service; @RequestMapping(method = RequestMethod.GET) public ModelAndView index(@PathVariable int id) { EditPersonBean bean = new EditPersonBean(); if (id > 0) { Person person = service.getPerson(id); bean.copyValuesToBean(person); } ModelAndView mav = new ModelAndView("editPerson"); mav.addObject("editPersonBean", bean); return mav; } 

但在我的post方法中,这个10的ID突然变为0,我相信这可能是导致此错误的原因?

 @RequestMapping(value = "/edit", method = RequestMethod.POST) public String save (EditPersonBean bean, Person person, @RequestParam(value = "file", required = false) MultipartFile file) { System.out.println("incoming id : " + bean.getId()); try { Blob blob = Hibernate.createBlob(file.getInputStream()); bean.copyBeanValuesToPerson(person,blob); service.updatePerson(person); } catch (IOException e) { e.printStackTrace(); } return "redirect:/person.html"; } 

然后可能是什么原因或错误是什么?

 public class EditPersonBean { private int id; private String firstName; private String lastName; private String email; private String phoneNumber; private String otherInfo; private Blob image; private String userName; private String password; public void copyValuesToBean(Person person){ setId((int) person.getId()); setFirstName(person.getFirstName()); setLastName(person.getLastName()); setEmail(person.getEmail()); setPhoneNumber(person.getPhoneNumber()); setOtherInfo(person.getOtherInfo()); setImage(person.getImage()); setUserName(person.getUserName()); setPassword(person.getPassword());; } @Entity public class Person { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "ID") private int id; @Column(name = "FIRSTNAME") private String firstName; @Column(name = "SECONDNAME") private String lastName; @Column(name = "EMAIL") private String email; @Column(name = "MobilePHONENUM") private String phoneNumber; @Column(name = "OTHER") private String otherInfo; @Column(name = "image") @Lob private Blob image; @NotEmpty @Size(min = 1, max = 50) @Column(name = "username") private String userName; @NotEmpty @Size(min = 1, max = 20) @Column(name = "password") private String password; public Person() { } public Person(int id, String firstName, String lastName, String email, String phoneNumber, String otherInfo, Blob image, String userName, String password) { setId(id); setFirstName(firstName); setLastName(lastName); setEmail(email); setPhoneNumber(phoneNumber); setOtherInfo(otherInfo); setImage(image); setUserName(password); setPassword(userName); } //Getters and setters... 

JPA课程:

 @Override public Person getPerson(int personId) { return (Person)session.getCurrentSession().get(Person.class, personId); } 

当hibernate无法找到需要更新的所有行时,通常会导致此错误。 这意味着当您尝试更新从数据库中提取的某些对象时,它们不再存在(或者从未存在过)。

这可能是因为另一个线程正在删除它们或者DB的隔离模式设置为read_uncommited,因此由另一个事务创建的行无法保存(由于事务失败)并且不再存在。

准确知道发生了什么的唯一方法是在Hibernate.cfg.xml配置中打开Hibernate语句日志记录。 这是因为堆栈跟踪中没有任何行号与执行实际Hibernate操作的代码部分相对应。 相反,操作被批处理,然后在事务关闭时(或者在批处理指定数量的操作之后)立即执行。

要启用Hibernate语句日志记录,

  true true true 

也就是说,上次遇到这个问题时,一个记录被一个不同的线程/事务中的一般HQL更新删除,然后当前的线程/事务试图按ID删除完全相同的记录。 不幸的是,由于事务是批处理的,所以在执行删除时不会看到它,而是在程序执行后的某个时刻。 因此需要打开语句记录以查看哪个实际的Hibernate操作触发了exception。

我遇到了类似的问题,我试图保存一个对象,其中他的id是一个原始字段(长),并且在创建对象时,id默认设置为0,而Hibernate假设我想要更新id = 0的行(显然不存在)。

我的解决方案是将id字段更改为Long(包装器),这样,当我创建一个新实例时,id被设置为null,而Hibernate理解我正在向数据库中插入一个新元素。
我希望它有所帮助。 谢谢。

100%解决方案:1确保表中的id是自动递增所有外键都不是null作为会话

只需在你的hibernate查询中输入save而不是saveOrUpdate 。 这是由于以前的日志,您的类正在生成一些以前存储在您的表中的其他ID。 因此,hibernate尝试使用相同的ID进行更新,并且它找不到具有该ID的行,因此它提供了staleStateException

  • 我收到此错误是因为我想更新数据并且我使用过

    service.update(用户);

  • 但是为了测试目的,我删除了清除User表并忘记将方法更改为

    service.saveOrUpdate(用户);

  • 因此,我改变了它,问题解决了。

有些时候我们使用生成器类来生成一行的主键…但是我们在程序中添加force它会得到stalestateException。

 student=new Student(); student.setId(4); student.setName("thatha"); student.setDept("dev"); try { transaction = session.beginTransaction(); session.save(student); transaction.commit(); System.out.println("student is updated"); } catch (HibernateException e) { e.printStackTrace(); transaction.rollback(); System.out.println("tx is rollback"); } 

添加级联以进行更新。 如果涉及外键,将解决问题。

检查作为Id(使用生成器类)映射到hibernate的Object的变量是否首先不包含任何过时值。

如果记录被任何其他线程或操作删除,但您的Id变量仍然包含过时值,并且当您更新数据库中的记录时,它会为您提供此exception,因为不会有给定ID的记录在DB中,因此您必须保存对象而不是更新,因为首先没有更新记录的余地

要不然

使用saveOrUpdate方法时,将id设置为null。