插入失败后恢复休眠会话状态 [英] recover Hibernate session state after a failed insert

查看:74
本文介绍了插入失败后恢复休眠会话状态的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下代码尝试使用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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆