Java 休眠删除错误:批量更新返回意外的行数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/21124361/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Hibernate Delete Error: Batch Update Returned Unexpected Row Count
提问by Kid Diamond
I wrote this method below that is suppose to delete a member record from the database. But when I use it in my servlet it returns an error.
我在下面写了这个方法,假设从数据库中删除成员记录。但是当我在我的 servlet 中使用它时,它返回一个错误。
MemberDao Class
MemberDao 类
public static void deleteMember(Member member) {
Session hibernateSession = HibernateUtil.getSessionFactory().getCurrentSession();
Transaction tx = hibernateSession.beginTransaction();
hibernateSession.delete(member);
tx.commit();
}
Controller Part
控制器部分
if(delete != null) {
HttpSession httpSession = request.getSession();
Member member = (Member) httpSession.getAttribute("member");
MemberDao.deleteMember(member);
nextPage = "ledenlijst.jsp";
}
HTTP Status 500
HTTP 状态 500
org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1
Sometimes it even throws this error when I try to execute the page multiple times.
有时,当我尝试多次执行页面时,它甚至会抛出此错误。
org.hibernate.exception.GenericJDBCException: Could not execute JDBC batch update
Does anybody know what exactly is causing these errors?
有谁知道究竟是什么导致了这些错误?
采纳答案by Ashish Jagtap
The error can be caused by several things. I'm not taking the credit for it, found it here.
该错误可能由多种原因引起。我不相信它,在这里找到它。
- Flushing the data before committing the object may lead to clear all object pending for persist.
- If object has primary key which is auto generated and you are forcing an assigned key
- if you are cleaning the object before committing the object to database.
- Zero or Incorrect ID: If you set the ID to zero or something else, Hibernate will try to update instead of insert.
- Object is Stale: Hibernate caches objects from the session. If the object was modified, and Hibernate doesn't know about it, it will throw this exception — note the StaleStateException
- 在提交对象之前刷新数据可能会导致清除所有等待持久化的对象。
- 如果对象具有自动生成的主键并且您正在强制分配一个键
- 如果您在将对象提交到数据库之前清理对象。
- 零或不正确的 ID:如果您将 ID 设置为零或其他内容,Hibernate 将尝试更新而不是插入。
- Object is Stale:Hibernate 缓存会话中的对象。如果对象被修改,并且 Hibernate 不知道它,它将抛出这个异常——注意 StaleStateException
Also look at this answerby beny23which gives a few further hints to find the problem.
另请查看beny23 的这个答案,它提供了一些进一步的提示来找到问题。
- In your hibernate configuration, set hibernate.show_sql to true. This should show you the SQL that is executed and causes the problem.
- Set the log levels for Spring and Hibernate to DEBUG, again this will give you a better idea as to which line causes the problem.
- Create a unit test which replicates the problem without configuring a transaction manager in Spring. This should give you a better idea of the offending line of code.
- 在您的休眠配置中,将 hibernate.show_sql 设置为 true。这应该向您显示已执行并导致问题的 SQL。
- 将 Spring 和 Hibernate 的日志级别设置为 DEBUG,这同样会让您更好地了解哪一行导致了问题。
- 创建一个单元测试来复制问题,而无需在 Spring 中配置事务管理器。这应该让您更好地了解有问题的代码行。
回答by ParagFlume
I was facing same issue. The code was working in the testing environment. But it was not working in staging environment.
我面临同样的问题。该代码在测试环境中工作。但它在登台环境中不起作用。
org.hibernate.jdbc.BatchedTooManyRowsAffectedException: Batch update returned unexpected row count from update [0]; actual row count: 3; expected: 1
The problem was the table had single entry for each primary key in testing DB table. But in staging DB there was multiple entry for same primary key. ( Problem is in staging DB the table didn't had any primary key constraints also there was multiple entry.)
问题是该表在测试数据库表中的每个主键都有一个条目。但是在登台数据库中,同一个主键有多个条目。(问题是在暂存数据库中,表没有任何主键约束,也有多个条目。)
So every time on update operation it gets failed. It tries to update single record and expect to get update count as 1. But since there was 3 records in the table for the same primary key, The result update count finds 3. Since expected update count and actual result update count didn't match, It throws exception and rolls back.
所以每次更新操作都会失败。它尝试更新单个记录并期望获得更新计数为 1。但由于表中有 3 条记录用于相同的主键,结果更新计数找到 3。由于预期更新计数和实际结果更新计数不匹配, 它抛出异常并回滚。
After the I removed all the records which have duplicate primary key and added primary key constraints. It is working fine.
在我删除了所有具有重复主键的记录并添加了主键约束之后。它工作正常。
回答by Julien
this is the solution for my case, maybe it will help you!
这是我的情况的解决方案,也许它会帮助你!
Actually it was a conversion problem between a database field type (timestamp on postgreSQL) and his equivalent property type (Calendar) on hibernate xml file. When Hibernate did this update request, it didn't retrieve the row because the request interrogate with a bad convert Calendar value. So I simply replaced property type "Calendar" in "Date" in Hibernate xml file and the problem was fixed.
实际上,这是一个数据库字段类型(postgreSQL 上的时间戳)和他在 hibernate xml 文件上的等效属性类型(日历)之间的转换问题。当 Hibernate 执行此更新请求时,它没有检索该行,因为该请求询问了错误的转换日历值。所以我简单地替换了 Hibernate xml 文件中“日期”中的属性类型“日历”,问题就解决了。
回答by arn-arn
i recently experienced this and what happened was that i used the update method and it was throwing an exception because there was no existing record. I changed the method to saveOrUpdate. It worked.
我最近经历了这个,发生的事情是我使用了更新方法并且它抛出了一个异常,因为没有现有的记录。我将方法更改为 saveOrUpdate。有效。
回答by sagneta
I experienced this same issue with hibernate/JPA 2.1 when using memcached as the secondary cache. You would get the above exception along with a StaleStateException. The resolution was different than what has been noted previously.
当使用 memcached 作为二级缓存时,我在 hibernate/JPA 2.1 中遇到了同样的问题。您将收到上述异常和 StaleStateException。该决议与之前提到的不同。
I noticed that if you have an operation that interleaves deletes and selects (finds) from within the same table and transaction, hibernate can become overwhelmed and report that stale state exception. It would only occur for us during production as multiple identical operations on different entities would occur on the same table. You would see the system timeout and toss exceptions.
我注意到,如果您有一个操作从同一个表和事务中交错删除和选择(查找),hibernate 可能会不堪重负并报告该陈旧状态异常。它只会在生产期间发生,因为对不同实体的多个相同操作会发生在同一张表上。您会看到系统超时并抛出异常。
The solution is to simply be more efficient. Rather than interleaving in a loop, attempt to resolve which items need to be read and do so, preferably in one operation. Then perform the delete in a separate operation. Again, all in the same transaction but don't pepper hibernate with read/delete/read/delete operations.
解决方案就是提高效率。与其在循环中交错,不如尝试解决需要读取的项目并这样做,最好在一个操作中进行。然后在单独的操作中执行删除。同样,所有这些都在同一个事务中,但不要通过读取/删除/读取/删除操作来进行休眠。
This is much faster and reduces the housekeeping load on Hibernate considerably. The problem went away. This occurs when you are using a secondary cache and won't occur otherwise as the load will be on the database for resolution without a secondary cache. That's another issue.
这要快得多,并大大减少了 Hibernate 的内务负担。问题就解决了。当您使用二级缓存时会发生这种情况,否则不会发生,因为负载将在没有二级缓存的情况下在数据库上进行解析。那是另一个问题。
回答by mdziob
In my case this exception was caused by wrong entity mapping. There were no cascade for relation, and referenced child entity wasn't saved before trying to reference it from parent. Changing it to
在我的情况下,此异常是由错误的实体映射引起的。关系没有级联,并且在尝试从父级引用它之前没有保存引用的子实体。将其更改为
@OneToMany(cascade = CascadeType.ALL)
fixed the issue.
解决了这个问题。
Surely best way to find cause of this exception is setting show_sql and DEBUG level for logs - it will stop just at the sql that caused the problem.
当然,查找此异常原因的最佳方法是为日志设置 show_sql 和 DEBUG 级别 - 它只会在导致问题的 sql 处停止。
回答by Marzieh Ghadirinia
I have had this problem,
我遇到过这个问题
I checked my code, there weren't any problems but when i checked my data I found out, I had two entities with the same id!
我检查了我的代码,没有任何问题,但是当我检查我的数据时发现,我有两个具有相同 ID 的实体!
So, the flush()
could not work, because it works one by one for batch updates and it found 2 rows. Therefore, it didn't update and threw exception, but it was my problem. I don't know if it works fine for you or not!
因此,flush()
无法工作,因为它对批量更新一一工作,并且发现了 2 行。因此,它没有更新并抛出异常,但这是我的问题。我不知道它是否适合你!
回答by Sergio Lema
The exception
org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1
use to be thrown when Hibernate notice that the entity he wants to flush to the database isn't exactly as it was at the beginning of the transaction.
唯一的例外
org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1
,当该实体他要刷新到数据库Hibernate的通知是不完全的,因为它是在事务开始时抛出的使用。
I described more in details two different use cases that happen to me here.
我在细节两种不同的使用情况是发生在我身上更多的描述在这里。