当前位置: 首页 > 知识库问答 >
问题:

HIbernate"StaleStateExcema:批处理更新从更新[0]返回意外的行计数;实际行计数:0;预期:1"

邵赞
2023-03-14

当现有用户发出请求时,该方法首先删除最旧的记录,然后再保存新请求。如果请求传入的速度不太快(使用Oracle数据库),下面的代码可以正常工作。

   public Request saveRequest(Request req)
   {
      String user = req.getUser();
      
      // Do a NamedQuery on the entity to pull all requests for user
      List<Request> requestList = getRequests(user);
      
      LOGGER.info("Request List size is " + requestList.size() + " for " + user);
      
      // Sort the list then delete the first/oldest request
      Comparator<Request> bySessionDate = Comparator.comparing(Request::getDate);
      Collections.sort(requestList, bySessionDate);
         
      LOGGER.info("Deleting request id " + requestList.get(0).getId());

      deleteById(requestList.get(0).getId());

      Request sreq = requestRepository.create(req);
      LOGGER.info("Saved request for user " + sreq.getUserId());
      return sreq;
   }

输出:

2021-01-20 00:39:12,167 INFO  [beez.service.RequestManager] (default task-4) Request List size is 250 for Bob
2021-01-20 00:39:12,168 INFO  [beez.service.RequestManager] (default task-4) Deleting request id 757A9B21E51D49199F2E182F68BC6BF7
2021-01-20 00:39:12,171 INFO  [beez.service.RequestManager] (default task-4) Deleted: 757A9B21E51D49199F2E182F68BC6BF7
2021-01-20 00:39:12,173 INFO  [beez.service.RequestManager] (default task-4) Saved request for user Bob
2021-01-20 00:39:15,375 INFO  [beez.service.RequestManager] (default task-3) Request List size is 250 for Bob
2021-01-20 00:39:15,375 INFO  [beez.service.RequestManager] (default task-3) Deleting request id 27239B85472C45EDA5495E98523295F3
2021-01-20 00:39:15,377 INFO  [beez.service.RequestManager] (default task-3) Deleted: 27239B85472C45EDA5495E98523295F3
2021-01-20 00:39:15,380 INFO  [beez.service.RequestManager] (default task-3) Saved request for user Bob

但是,如果用户以非常快速的方式提交请求,即happy clicker,则相同的代码会生成StaleStateException错误。

2021-01-20 00:42:31,307 INFO  [beez.service.RequestManager] (default task-3) Request List size is 250 for Bob
2021-01-20 00:42:31,307 INFO  [beez.service.RequestManager] (default task-3) Deleting request id 55E43DF4D83E4BF5AD73DE47A49B0DA9
2021-01-20 00:42:31,310 INFO  [beez.service.RequestManager] (default task-3) Deleted: 55E43DF4D83E4BF5AD73DE47A49B0DA9
2021-01-20 00:42:31,313 INFO  [beez.service.RequestManager] (default task-3) Saved request for user Bob
2021-01-20 00:42:31,332 INFO  [beez.service.RequestManager] (default task-7) Request List size is 250 for Bob
2021-01-20 00:42:31,332 INFO  [beez.service.RequestManager] (default task-7) Deleting request id 55E43DF4D83E4BF5AD73DE47A49B0DA9
2021-01-20 00:42:31,492 ERROR [org.jboss.as.ejb3.invocation] (default task-7) WFLYEJB0034: EJB Invocation failed on component RequestManager for method public beez.entity.RequestManager service.RequestManager.saveRequest(beez.entity.RequestManager): javax.ejb.EJBTransactionRolledbackException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1
.
.
.
Caused by: org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1

似乎在下一条记录出现之前,代码还没有时间完成更改,导致代码尝试删除同一条记录两次。除了在这种方法之前改变前端或其他东西,还有什么方法可以解决这个问题吗?

我尝试了@Transactional和@Lock选项,但没有成功。在该线程中花费了大量时间,但解决方案要么不起作用,要么不适用:Hibernate-批量更新从更新中返回了意外的行数:0实际行数:0预期:1

共有1个答案

岳炎彬
2023-03-14

如果用户不希望快速点击,强烈建议您考虑在前面取消对API请求的公告,以跳过背靠背的请求/事件。

正如您所说的,由于加载到单个会话中的实体与数据库的当前状态不一致,问题正在发生。

这可以通过多种方式解决,比如使用悲观锁定(选择更新)带来的性能瓶颈,同步方法。。。。等

最简单的处理方法是使用JPA查询进行删除,并在数据库级别进行排序,因此这始终适用于记录表的当前状态。

delete from request where id= (select req.id from request req left join user usr on usr.id = req.userId where usr.userId=? order by req.date LIMIT 1)

请根据您的实体设计更正以上查询。

 类似资料:
  • 我不明白为什么我会犯这样的错误,我的头撞在墙上已经好几个小时了。 当试图删除数据库中我没有使用Hibernate添加的任何行(即通过常规SQL输入的数据库的所有现有行)时,上面的代码给了我一个错误。 如果我在应用程序中使用Hibernate插入一行,那么就可以完全删除该行。 我不能理解的是,我先从数据库中获取一个用户,这样我就知道这个用户存在。 我已经检查了Hibernate SQL,在运行sel

  • 问题内容: 我收到以下hibernate错误。我能够确定导致问题的功能。不幸的是,函数中有多个数据库调用。由于hibernate在事务结束时刷新会话,因此我找不到导致问题的行。下面提到的hibernate错误看起来像是一般错误。甚至都没有提到哪个Bean导致了问题。有人熟悉这个hibernate错误吗? 问题答案: 没有交易的代码和映射,几乎不可能调查问题。 但是,要更好地了解导致问题的原因,请尝

  • 我和冬眠有麻烦了。 我有个例外 我试图显示数据库中的日期,我的一列是char,在我的类中有一个 ' 我创建了一个来进行转换 `公共类FilialStatusType扩展了TypeHibernate{public static final String TYPE=“FilialStatusType”; ### 有人能帮我吗?

  • 当我试图保存预订到DB,我得到了。在我的情况下,我有一个预订实体,预订号是主键,而不是自动增量。所以我的逻辑是: > 生成预订号并将其设置为预订。 调用。 顺便说一下,我正在使用hibernate3 spring MySql5。5并在tomcat6中运行,有关更多详细信息,请参阅我的编码和日志: 预订实体 预订DAO保存功能 当我的struts2操作调用save函数来保存预订时,它将得到以下错误

  • 当我试图从spring mvc应用程序更新数据库中的值时,我遇到了以下错误: 所以我的实际错误似乎是数据库中的ID和正在更新的内容。在我的GET方法中,我得到的是当前ID,在本例中是10。 但在我的post方法中,这个ID是10,突然变成了0,我相信这可能是这个错误的原因? 那么,这可能是什么原因,还是错误是别的什么? JPA课程:

  • 问题内容: 我在下面编写了此方法,该方法假定是从数据库中删除成员记录。但是,当我在servlet中使用它时,它将返回错误。 会员班 控制器部分 HTTP状态500 有时,当我尝试多次执行页面时,甚至会引发此错误。 有人知道究竟是什么引起这些错误吗? 问题答案: 该错误可能是由多种原因引起的。我不为此而功劳,在这里找到了它。 在提交对象之前刷新数据可能会导致清除所有等待持久化的对象。 如果对象具有自