当前位置: 首页 > 面试题库 >

插入失败后恢复休眠会话状态

乐华晖
2023-03-14
问题内容

以下代码尝试Item使用Spring + Hibernate
将对象插入数据库。该项目具有一个整数ID字段作为主键,以及一name列,该列受到唯一约束(简化示例)。
我知道该项目的ID为null(该项目是临时的),但是由于对名称字段的唯一约束,插入操作仍然可能失败。

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)
}

我需要此代码在一个事务中针对许多项目循环运行,这就是为什么我尝试在插入失败的情况下发出更新的原因。

但是,在插入失败之后,hibernate会话处于一种奇怪的状态,当我发出select语句从db获取项目时,将引发 原始 异常。

我尝试session.evict()在插入失败后使用,但无济于事。任何的想法?

这是选择失败后在控制台中看到的内容。Hibernate在select语句上失败,但仍会打印有关前一个insert语句的信息。

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)

PS:请不要告诉我有关hibernate的saveOrUpdate方法的信息,我知道它的作用。


问题答案:

抛出数据库异常后,Hibernate不保证有关会话的任何内容。您应该回滚。如果我理解Bozho的建议,他是说您应该首先从name列阅读,以确保插入不会失败。我感觉合理。



 类似资料:
  • 问题内容: 我在hibernate和延迟加载方面遇到问题。 背景:我有一个Spring MVC Web应用程序,我将Hibernate用于持久层。我正在使用OpenSessionInViewFilter使我能够在视图层中延迟加载实体。我正在扩展HibernateDaoSupport类,并使用HibernateTemplate保存/加载对象。一切都进行得很好。直至现在。 问题:我有一个可以通过Web

  • 问题内容: 在引发约束违规异常之后,有什么方法可以继续使用线程绑定的hibernate会话吗?我在这里举一个简短的例子: 从现在开始,hibernate会话完全没有用,即使对于只读操作,例如使用OpenSessionInView模式在视图中呈现惰性集合。 问题答案: Session的文档指出, 如果Session引发异常,则必须回滚事务并丢弃会话。 发生异常后,会话的内部状态可能与数据库不一致。。

  • 我正在尝试构建我的项目,但由于以下错误而失败: "运行命令-失败![错误]运行cordova准备时出错(退出代码1): 我尝试使用以下方法安装cordova插件: > $ionic cordova插件添加cordova插件失眠$npm安装--保存@ionic native/失眠 Cordova插件添加https://github.com/EddyVerbruggen/Insomnia-PhoneG

  • 问题内容: 当我按如下方式调用session.begin事务方法时: 然后我得到以下异常消息 造成此错误的原因是什么? 问题答案: 更新: 我想调用并不能保证该会话实际上是打开的。第一次,您应该使用 代替。该建议实际上与您找到的页面一致。 之前: 根据到目前为止的可用信息,我们可以得出结论,错误的原因是会话未打开;-)

  • 问题内容: 下面的函数是我在Web应用程序中具有的按钮的actionListener,我正在从数据库中的表中删除旧选择的行,并将新行插入数据库中。 我一直在例外:会话关闭!有人可以解释一下如何在hibernate状态下关闭会话(自动吗?)以及如何使用它们。 这是该异常的详细堆栈跟踪: 谢谢, 问题答案: 在Hibernate会话显然配置为基于请求的情况下,您在会话范围内的受管Bean中使用了延迟获

  • 问题内容: 一个只有一个数据库的hibernate会话将保持多少个连接? 问题答案: 在给定的时间,给定的会话将仅保留一个连接,您可以使用connect()方法进行访问。 使用reconnect()方法可以更改所使用的连接。