2014-01-14 45 views
19

我写下这个方法是假设从数据库中删除成员记录。但是当我在我的servlet中使用它时,它会返回一个错误。休眠删除错误:批量更新返回意外的行计数

MemberDao类

public static void deleteMember(Member member) { 
    Session hibernateSession = HibernateUtil.getSessionFactory().getCurrentSession(); 
    Transaction tx = hibernateSession.beginTransaction(); 
    hibernateSession.delete(member); 
    tx.commit(); 
} 

控制器部

if(delete != null) { 
    HttpSession httpSession = request.getSession(); 
    Member member = (Member) httpSession.getAttribute("member"); 

    MemberDao.deleteMember(member); 

    nextPage = "ledenlijst.jsp"; 
} 

HTTP状态500

org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1 

逊当我尝试多次执行页面时,它甚至会抛出这个错误。

org.hibernate.exception.GenericJDBCException: Could not execute JDBC batch update 

有没有人知道究竟是什么导致了这些错误?

+0

可能的重复:http://stackoverflow.com/questions/3853106/org-hibernate-stalestateexception-batch-update-returned-unexpected-row-count-fr –

+0

你是否试图删除同一个'member'两次? –

回答

42

错误可能是由几件事引起的。我没有拿它的功劳,发现它here

  1. Flushing the data before committing the object may lead to clear all object pending for persist.
  2. If object has primary key which is auto generated and you are forcing an assigned key
  3. if you are cleaning the object before committing the object to database.
  4. Zero or Incorrect ID: If you set the ID to zero or something else, Hibernate will try to update instead of insert.
  5. 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

也期待在this answerbeny23这给一些提示,进一步查找问题。

  • 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.
+2

对象是陈旧的:Hibernate从会话中缓存对象。如果对象被修改,并且Hibernate不知道它,它会抛出这个异常 - 注意StaleStateException –

0

我面临同样的问题。代码在测试环境中工作。但它在分段环境中不起作用。

org.hibernate.jdbc.BatchedTooManyRowsAffectedException: Batch update returned unexpected row count from update [0]; actual row count: 3; expected: 1 

问题是表中有测试数据库表中每个主键的单个条目。但是在分段DB中,对于相同的主键有多个条目。 (问题是暂存数据库表中没有任何主键约束还有多个条目。)

因此,每次更新操作时都会失败。它试图更新单个记录,并期望将更新计数设置为1.但是由于表中存在相同主键的3条记录,因此结果更新计数为3.由于预期更新计数和实际结果更新计数不匹配它抛出异常并回滚。

之后,我删除了所有具有重复主键和添加主键约束的记录。它工作正常。

0

这是我的情况的解决方案,也许它会帮助你!

实际上,它是一个数据库字段类型(postgreSQL上的时间戳)和他在hibernate xml文件上的等效属性类型(日历)之间的转换问题。 当Hibernate执行此更新请求时,它没有检索该行,因为该请求使用错误的转换日历值进行查询。 所以我简单地在Hibernate xml文件的“Date”中替换了属性类型“Calendar”,并且问题得到了解决。

0

我最近经历过这个,发生了什么事情是我使用了更新方法,并且因为没有现有记录而引发异常。我将该方法更改为saveOrUpdate。有效。

0

当使用memcached作为二级缓存时,我遇到了与hibernate/JPA 2.1相同的问题。你会得到上面的异常以及一个StaleStateException。该决议与之前提到的不同。

我注意到,如果你有一个交叉操作,删除和选择(发现)从同一个表和事务,hibernate可能会变得不堪重负,并报告该陈旧的状态异常。它只会在生产过程中发生,因为在同一张桌子上会出现不同实体上的多个相同操作。你会看到系统超时并抛出异常。

解决方案是简单地更高效。而不是在一个循环中交错,试图解决哪些项目需要阅读和这样做,最好在一个操作。然后在单独的操作中执行删除。同样,所有在同一个事务中,但不要用读/删除/读/删除操作胡闹休眠。

这要快得多,并且大大减少了Hibernate的内务负载。问题消失了。当您使用辅助缓存时会发生这种情况,否则不会发生,因为负载将在数据库上进行解析而无需辅助缓存。这是另一个问题。

1

在我的情况下,这个异常是由错误的实体映射引起的。关系没有级联,并且在尝试从父级引用它之前,引用的子实体未保存。更改为

@OneToMany(cascade = CascadeType.ALL) 

修复了这个问题。

确实找到这个异常的原因的最好方法是设置日志的show_sql和DEBUG级别 - 它只会停止在导致问题的sql。

0

我有这个问题,

我检查了我的代码,没有发现任何问题,但是当我检查我的数据,我发现,我有两个实体使用相同的ID!

因此,flush()无法正常工作,因为它对批量更新一个接一个地工作,并且找到2行。因此,它没有更新和抛出异常,但这是我的问题。我不知道它是否适合你的工作!

0

例外 org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1 使用时,该实体他要​​刷新到数据库Hibernate的通知是不完全的,因为它是在事务开始时抛出。

我更详细地描述了两种不同的使用情况,发生在我身上here

相关问题