吕克让的资料库 - lhelper's repository

克己服人,礼智谦让!
Weblcome to lhelper's repository!

Tuesday, July 04, 2006

 

Hibernate 的 "SQL insert, update or delete failed (row not found)" 异常

关键字:hibernate, trigger(触发器), store procedure(存储过程), NonBatchingBatcher,rowCounts, updateCount


在借助hibernate[1] 执行更新操作,包括插入(insert)/修改(update)/删除(delete)操作的过程中,如果数据库一方返回的update count 与 hibernate 所预期的 count[2] 不同,那么hibernate 的Batcher 就会抛出异常:



HibernateException("SQL insert, update or delete failed (row not found)");

下面是一段完整的错误信息:


[ERROR][tcpConnection-8080-3] - Could not synchronize database state with session
org.springframework.orm.hibernate.HibernateSystemException: SQL insert, update or delete failed (row not found); nested exception is net.sf.hibernate.HibernateException: SQL insert, update or delete failed (row not found)
net.sf.hibernate.HibernateException: SQL insert, update or delete failed (row not found)
at net.sf.hibernate.impl.NonBatchingBatcher.addToBatch(NonBatchingBatcher.java:25)

该异常通常是由于更新过程中所涉及的触发器(trigger) 或存储过程(store procedure) 中又包含有更新操作,使得数据库返回的update count 为整个过程中所涉及的所有count 的总和。


一般情况下可以通过在触发器或存储过程中加入 'SET NOCOUNT ON' 声明的方式来解决问题,如:
CREATE TRIGGER tri_t1_delete
ON t1
FOR DELETE
AS
SET NOCOUNT ON -- set 'NOCOUNT' to ON, so the count (indicating the number of rows affected by a Transact-SQL statement) is not returned.
DELETE t2
FROM t2 AS a INNER JOIN deleted AS b
ON a.id=b.id



但似乎也有例外,如:
http://sourceforge.net/forum/message.php?msg_id=3074706



下面是hibernate(2.1)的NonBatchingBatcher (Batcher 的具体实现)比较数据库一方返回的update count 与程序预期的 count 是否相同并伺机抛出异常的程序片断:


public void addToBatch(int expectedRowCount) throws SQLException, HibernateException {
int rowCount = getStatement().executeUpdate();
//negative expected row count means we don't know how many rows to expect
if ( expectedRowCount>0 && expectedRowCount!=rowCount )
throw new HibernateException("SQL insert, update or delete failed (row not found)");
}



注:
[1]: 笔者使用的是2.1 版本的hibernate 发行包
[2]: 通常是 1,


参考:
About 'SET NOCOUNT ON'
http://msdn.microsoft.com/library/en-us/tsqlref/ts_set-set_3ed0.asp?frame=true


Comments: Post a Comment



<< Home

Archives

June 2004   November 2005   July 2006   August 2006  

This page is powered by Blogger. Isn't yours?