java - 为什么我的 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 中的行为一样......
如果有人有一些线索可以分享,我将不胜感激。
解决方案
再一次:这是刷新模式的问题。
默认情况下,休眠使用自动刷新模式,这告诉系统有时可能会调用刷新以确保不返回过时状态。
当您在 3.6 上时,您的会话在每次更新调用期间都会自动刷新。(为什么要存储未修改的状态,如果用户正在调用更新:做到这一点,并默认遵守 AUTO 模式)。
现在 5 正在尝试提高应用程序性能并减少与数据库服务器交互的次数。因此在每次更新/创建调用期间不会刷新。但是,当您尝试对特定类型的对象执行查询时,它会检查会话的状态,并发现对查询类型的对象进行了修改,因此在精确 SELECT 之前执行刷新。
为了克服这个问题:当您期望时手动调用刷新。我可以假设,您依赖于提到的测试中的数据库唯一检查,并且验证仅在刷新期间发生。这将是最简单的修改方法。另一种方法是将纯数据库的唯一检查提取到基于服务的...
或者只是将休眠配置更改为使用 FlushMode.ALWAYS。
推荐阅读
- mitmproxy - 如何在 Mitmproxy 插件中发出网络请求
- c# - Internet 连接检查 API (wininet.dll) 不起作用 | C# WPF
- git - 如何 git checkout “下一个” 提交
- java - 如何使用 Java 客户端代码获取 OAuth2.0 访问令牌并使用此令牌调用 RESTFul Web 服务
- json - 无法在颤振飞镖中使用 REST API 发送拦截的短信
- amazon-emr - Trino (PrestoSQL) 的上一年度迄今为止的窗口函数
- javascript - 如何使用 RowGroup 显示图像?
- arrays - 无法从非空数组中获取元素
- matlab - 如何在 MATLAB 中正确绘制数值算法的误差
- vim - 无法在 gVim 中禁用滚轮