8

我是 Hibernate 的新手,正在开发一个使用它的 Web 项目。

我有一个名为 area 的对象,它有一个 date object( java.sql.Timestamp) 属性 modifiedDate。当我创建一个新对象时,modifieDate 为空,然后将其发送到getHibernateTemplate().saveOrUpdate(area);我自己的扩展类中,org.springframework.orm.hibernate3.support.HibernateDaoSupport并使用当前时间戳设置并保存在数据库中。在数据库中,它保存为datetime.

我的问题是大多数情况下,对象的更新日期与保存在数据库中的日期相比相差 1 毫秒,如果在不重新加载页面的情况下尝试更新任何内容,则会导致此异常:

an org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect)

随后从数据库中获取对象时,正确的日期没有问题,只是在创建时它得到了错误的值。

有没有办法在 SaveOrUpdate 获得正确的 modifiedDate?

如果需要映射使用<timestamp name="modifiedDate" column="ModifiedDate"/>并且所有测试都在本地主机上运行,​​所有测试都在同一台机器上运行。

我已经有一个解决方法,通过getHibernateTemplate().refresh(area);在 saveOrUpdate 之后立即调用我得到正确的时间戳,但我仍然想知道是否有办法在 saveOrUpdate 获得正确的 modifiedDate。

4

1 回答 1

4

我的理论:

发生的情况是,您在数据库端使用的数据类型比在 Java 端更不精确,因此在生成特定于 DB 的 SQL 期间,持久保存到数据库的值正在失去精度(或以某种方式舍入,见下文) . 以下是如何确定的:

  1. 请记住,Hibernate 通过生成在数据库中执行的 SQL 语句来工作。为了诊断这样的 Hibernate 映射问题,您需要查看正在执行的 SQL 以便准确了解发生了什么。

  2. 打开 Hibernate 的“显示 SQL”设置。这将导致 Hibernate 转储数据库上正在执行的原始 SQL。

  3. 检查测试中的日志。它将有助于toString在您的类上实现并记录值以与 SQL hibernate 为INSERT. SQL 语句中的值是否与 Java 时间戳字段的值匹配?

您应该检查数据库DATETIME类型的精度设置。例如,在 SQL Server 上,DATETIME实现毫秒舍入(请参阅“准确性”字段),这实际上会导致毫秒值的精度损失。您将需要更改列映射到的 Java 类型或更改数据库中列的类型,具体取决于您的精度需求。

于 2012-08-18T16:12:10.210 回答