首页 > 解决方案 > 为什么我的 Hibernate DAO 在升级到 5 后表现不同?

问题描述

我有一个在 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 中的行为一样......

如果有人有一些线索可以分享,我将不胜感激。

标签: javahibernatehibernate-mapping

解决方案


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

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

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

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

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

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


推荐阅读