【问题标题】:Why is my Hibernate DAO behaving differently after upgrading to 5?为什么我的 Hibernate DAO 在升级到 5 后表现不同?
【发布时间】:2018-06-07 07:46:55
【问题描述】:

我有一个在 3.6 上运行的旧项目。我刚刚更新到 Hibernate 5,我有几个不再运行的测试。

例子:

@Test
public void testConflictingKeyword() {

    Location loc = locationDao.findByKeyword("l1");

    try {
        loc.setKeyword("l2");
        locationDao.update(loc);
        fail("should not be able to update entity, another entity with keyword exists");
    } catch (Exception e) {}
}

此测试在 3.6 上运行良好。我可以看到调用了 dao 更新,并且我得到了一个 constrantviolationexception。

但是,升级到 5 之后,update 方法就不再调用了。

但是,如果我在更新后添加另一个locationDao.findByKeyword("l1") 方法调用,则会执行更新sql!

我怀疑它与自动提交和刷新有关,但我不确定在哪里查看并使 5 的行为与 3.6 中一样...

如果有人能提供一些线索,我将不胜感激。

【问题讨论】:

  • 您是否在更新方法中调用了 flush()?
  • 不,我没有。它一直有效,所以我没有看到任何需要。
  • 你能用hibernate 4测试它吗?只是为了弄清楚他们在哪些方面改变了您的问题?

标签: java hibernate hibernate-mapping


【解决方案1】:

再一次:这是刷新模式的问题。

默认情况下,休眠使用自动刷新模式,这告诉系统有时可能会调用刷新以确保不返回过时状态。

当您使用 3.6 时,您的会话在每次更新调用期间都会自动刷新。 (为什么要存储未修改的状态,如果用户正在调用更新:做到这一点,并默认遵守 AUTO 模式)。

现在 5 正在尝试提高应用程序性能并减少与数据库服务器交互的次数。因此在每次更新/创建调用期间不会刷新。但是,当您尝试对特定类型的对象执行查询时,它会检查会话的状态,并发现对查询类型的对象进行了修改,因此在精确 SELECT 之前执行刷新。

为了克服这个问题:在您期望的时候手动调用刷新。我可以假设,您依赖于提到的测试中的数据库唯一检查,并且验证仅在刷新期间发生。这将是最简单的修改方法。另一种方法是将纯数据库的唯一检查提取到基于服务的...

或者只是将休眠配置更改为使用 FlushMode.ALWAYS。

【讨论】:

  • 我认为你是对的,但没有完全理解 3.6 的部分:“为什么要存储未修改状态,如果用户正在调用更新:做到这一点,并默认遵守 AUTO 模式” ..你能详细说明一下吗,或者指向文档?
  • 您好,感谢您的宝贵意见。我没有得到一件事——我没有,也从来没有自己配置过 FlushMode。这是否意味着在 3.6 中默认的刷新模式不是自动的?你知道有什么记录吗?
【解决方案2】:

似乎他们改变了 Hibernate 5.2 中 AUTO Flushmode 的行为。我只能在短时间内找到private blog

从 Hibernate 5.2 开始,如果您使用 JPA 引导 Hibernate(例如 persistence.xml),那么即使是 Hibernate FlushType.AUTO 也会运行 就像它的 JPA 对应物一样。仅当您使用引导 Hibernate 时 原生机制,Hibernate Session 会使用传统的吗? FlushType.AUTO 行为。

干杯,雷纳

【讨论】:

    猜你喜欢
    • 2020-04-30
    • 1970-01-01
    • 2021-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-24
    • 2015-12-03
    • 1970-01-01
    相关资源
    最近更新 更多