Java org.hibernate.ObjectNotFoundException在查询迭代时发生

Java org.hibernate.ObjectNotFoundException在查询迭代时发生,java,hibernate,Java,Hibernate,我试图在以下代码段中定位一个bug: Query bookLogs = session.createQuery("FROM BookLog log"); for (Iterator it = bookLogs.iterate(); it.hasNext();) { BookLog bookLog = (BookLog) it.next(); bookNo = bookLog.getNo(); ... session.delete(bookLog); session.flush

我试图在以下代码段中定位一个bug:

Query bookLogs = session.createQuery("FROM BookLog log");
for (Iterator it = bookLogs.iterate(); it.hasNext();) {
  BookLog bookLog = (BookLog) it.next();
  bookNo = bookLog.getNo();
  ...
  session.delete(bookLog);
  session.flush();
}
bookLog.getNo中很少出现以下异常:

org.hibernate.ObjectNotFoundException: No row with the given identifier exists: [de.store.Books.BookLog#2343]
我假设在调用iterator.remove时,在删除db条目时发生冲突

BookLog不引用任何表,其映射也相应地简单。

作为Query.interate返回代理迭代器,只获取实体的id

执行1+N SQL查询。第一个查询只返回所有记录的标识符,当返回的迭代器被迭代时,每次执行一个单独的SQL查询,该查询包含WHERE子句,如WHERE id=N。如果记录存在于缓存中,则执行第一个查询,而不执行其余的N个查询,并从缓存中获取记录

这就是并发修改问题。当您执行查询时

for (Iterator it = bookLogs.iterate(); it.hasNext();) {
给定的BookLog存在,其id返回到迭代器中。迭代时,对于每个

 bookNo = bookLog.getNo()
执行单独的SELECT查询,但此时,整个表可能已被另一个并发操作修改。具有给定id的行不再存在,并引发异常。
为了避免这种情况,您必须使用适当的事务隔离或使用Query.getResultList。这将在单个查询中返回所有结果。然而,不能保证当您试图删除返回的实体时,它仍然在数据库中

为什么要将迭代器对象强制转换为book?相反,您可以尝试BookLog BookLog=BookLog it.next;是因为你想移除一些不存在的东西吗?我想它会返回一个null,那么bookNo是什么?@Antoniossss Integer bookNo