【问题标题】:what are some common problems with Hibernate/persistence?休眠/持久性有哪些常见问题?
【发布时间】:2012-07-03 03:47:17
【问题描述】:

我有一个应用程序我想针对与 Hibernate 和/或持久性相关的可能问题进行测试。

还有什么问题?我如何复制它们(字面意思)?你如何从他们身上恢复过来?

说清楚:我说的是多线程集群环境(最复杂的一个)。

我的:

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

转载:

  • 加载对象。
  • 使用 HQL 更新。
  • 尝试更新(保存)加载的对象。

句柄:不确定...

【问题讨论】:

    标签: java hibernate testing persistence


    【解决方案1】:

    延迟加载是您会遇到的大问题之一,尤其是当您遵循标准 DAO 模式时。你最终会得到延迟加载的集合,但是在你的 DAO 层出来后,spring(或者如果你不使用 spring,或者其他东西)可能会关闭会话。

    public class MyDaoImpl implements MyDao {
       @Override
       @Transactional
       public void save(MyObject object) { ... }
    }
    

    在这种情况下,当“保存”调用完成时,如果您不在另一个事务中,spring 将关闭您的会话。因此,任何对延迟加载对象的调用都会抛出 LazyInitializationException。

    处理此问题的典型方法是将会话绑定到当前线程。在 webapps 中,您可以使用 OpenSessionInViewFilter 轻松完成此操作。对于命令行,您可能需要编写一个实用方法来创建会话,绑定到当前线程,然后在完成后解除绑定。您可以在整个网络上找到这方面的示例。

    关于集合的主题,如果您使用“更新”方法(这也是您通常使用标准 DAO 模式执行的操作),您必须小心不要替换集合实例,而是应该操作已经到位的集合。否则,hibernate 将很难确定需要添加/删除/更新的内容。

    【讨论】:

    • 很好的答案,希望有更多类似的东西。谢谢:)
    【解决方案2】:

    您观察到的问题是数据的并发修改之一。 Hibernate 有 many possible solutions 来处理这个问题。

    本质上,问题在于两个线程(或集群中的两台机器)同时作用于同一条数据。考虑这个例子:

    machine 1: reads the data and returns it for editing somewhere else
    machine 2: also reads the data for modification
    machine 1: updates the data and commits.
    machine 2: tries to do an update and commit.
    

    当第二台机器尝试提交其更改时会发生什么?当机器 2 处理数据时,Hibernate 将看到数据已更改。也就是说,机器 2 的更新基于陈旧数据。 Hibernate 不能总是合并这两个更改(也不是总是需要的行为),所以它通过抛出 org.hibernate.StaleObjectStateException

    来拒绝第二次更新

    正如我上面提到的,Hibernate 为您提供了许多选项来解决这个问题。也许最简单的方法是在您的数据对象上使用@Version 添加一个版本字段。 Hibernate 会自动维护数据的“版本”。每当发生更新时,Hibernate 会自动更改版本。您的工作是检查在您读取数据和更新数据之间版本没有发生变化。如果它们不匹配,您可以采取一些措施来处理问题(即告诉用户)。有一些更复杂的技术可以防止并发更新,但这是最简单的。

    【讨论】:

    • 我知道 Oleski,但还没有具体的计划来处理它。顺便说一句,我使用版本控制。将不得不调查它,因为您提供的链接没有提供明确的解决方案。不过谢谢!
    • 您能说出一两个“防止并发更新的复杂技术”吗?我真的很感兴趣。
    • 当然。我上面提供的链接讨论了三种技术:应用程序版本检查(您当前正在执行)、扩展会话和自动版本控制、分离对象和自动版本控制。最重要的是,您可以使用悲观锁定,它可以让您更明确地控制您的数据。
    【解决方案3】:

    获取过多的数据可能是您在使用 ORM 工具时可能遇到的最大问题,因为它可以很容易地加载比需要更多的数据。如果测试数据量相当小,这个问题在开发/测试场景中不会复制,一旦数据开始在生产中积累,数据访问层就会成倍地变慢。

    可能会出现很多问题:

    • 缺少批量更新
    • 缺少语句缓存
    • 锁定过多
    • 数据库往返次数过多
    • 产生低效 SQL 语句的奇异关联

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-29
      • 1970-01-01
      • 1970-01-01
      • 2011-03-30
      • 2012-10-07
      • 2012-07-22
      相关资源
      最近更新 更多