插入失败后恢复休眠会话状态 [英] recover Hibernate session state after a failed insert
问题描述
以下代码尝试使用Spring + Hibernate将Item
对象插入数据库.该项目具有一个整数ID字段作为主键,以及一个name
列,该列受到唯一约束(简化示例).
我知道该项目的ID为null(该项目是临时的),但是由于对名称字段的唯一约束,插入操作仍然可能失败.
The following code tries to insert an Item
object to the db, using Spring+Hibernate. The Item has an Integer id field as primary key, as well as a name
column which is subject to a unique constraint (simplified example).
I know that the item's id is null (the item is transient) however the insert may still fail due to the unique constraint on the name field.
try {
getHibernateTemplate().save(myItem);
getHibernateTemplate().flush(); // exception thrown here if the name is not unique
}
catch (DataIntegrityViolationException e) {
Item itemFromDb = (Item) getHibernateTemplate()
.find("from Item item where item.name = ?",
myItem.getName()).get(0);
//
// copy some properties from myItem to itemFromDb
//
getHibernateTemplate.update (itemFromDb)
}
我需要此代码在一个事务中针对许多项目循环运行,这就是为什么我尝试在插入失败的情况下发出更新的原因.
I need this code to run in a loop for many items, all in one transaction, that's why I am trying to issue an update if the insert fails.
但是,在插入失败之后,休眠会话处于一种奇怪的状态,当我发出select语句从db获取项目时,会抛出原始异常.
However, after the insert fails, the hibernate session is in a strange state, and when I issue the select statement to obtain the item from the db, the original exception is thrown.
我在插入失败后尝试使用session.evict()
,但无济于事.有什么主意吗?
I tried using session.evict()
after the insert fails, but to no avail. Any idea?
这是选择失败后在控制台中看到的内容. Hibernate在select语句上失败,但仍会打印有关前一个insert语句的信息.
This is what I see in the console after the select fails. Hibernate fails on the select statement but still prints information about the previous insert statement.
WARN [http-8080-1] hibernate.util.JDBCExceptionReporter (JDBCExceptionReporter.java:77) - SQL Error: 2627, SQLState: 23000
ERROR [http-8080-1] hibernate.util.JDBCExceptionReporter (JDBCExceptionReporter.java:78) - Violation of UNIQUE KEY constraint 'unq_Item_name'. Cannot insert duplicate key in object 'items'.
ERROR [http-8080-1] event.def.AbstractFlushingEventListener (AbstractFlushingEventListener.java:301) - Could not synchronize database state with session
org.hibernate.exception.ConstraintViolationException: could not insert: [com.sample.Item]
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:71)
P.S.请不要告诉我有关休眠的saveOrUpdate方法的信息,我知道它的作用.
推荐答案
一旦引发数据库异常,Hibernate便不保证有关会话的任何内容.您应该回滚.如果我理解Bozho的建议,他是说您应该先从name列阅读,以确保插入不会失败.对我来说很有道理.
Hibernate does not guarantee anything about a session once a database exception is thrown. You are supposed to roll-back. If I understand Bozho's suggestion, he's saying that you should read from the name column first to ensure that the insert won't fail. Makes sense to me.
这篇关于插入失败后恢复休眠会话状态的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!