我有一个带有Spring @Transactional
注释的JUnit 4测试用例,用于保存对象,然后尝试找到它。当我使用这个实现时,测试用例通过了:
@Override
public EventSummary findEventSummaryById(Integer id) {
return em.find(EventSummary.class, id);
}
当我使用此实现时失败(然后更改我在测试用例中调用的方法):
@Override
public EventSummary findEventSummary(Integer id) {
Query query = em.createQuery("select es from EventSummary as es where es.id = :id");
query.setParameter("id", id);
EventSummary result = (EventSummary) query.getSingleResult();
return result;
}
答案 0 :(得分:3)
实体位于当前会话(实体管理器)中 - 它处于持久状态,等待刷新。 get方法首先检查会话的内容,如果没有找到则转向底层数据库。在您的情况下,实体刚刚保存在同一个会话中,因此找到并返回该实体。
更新:事实证明问题是使用了不正确的事务管理器,因此实体尚未刷新到数据库。见Pascal的解释。
答案 1 :(得分:3)
如果您使用的是默认刷新模式(AUTO
),并且如果您在事务中执行查询,则JPA规范保证Query不会返回过时或不正确的数据:
3.6.2查询和FlushMode
刷新模式设置会影响 查询结果如下。
在a中执行查询时 交易,如果
FlushModeType.AUTO
在Query
对象上设置,或者如果是。{ 持久性的刷新模式设置 上下文是AUTO
(默认值)和a 冲洗模式设置尚未完成 为Query
对象指定的 持久性提供者负责 确保所有更新 中的所有实体的状态 持久性上下文可以 可能会影响结果 查询对于处理是可见的 查询。持久性提供者 实施可以实现这一点 将这些实体刷新到 数据库或通过其他方式。如果 设置FlushModeType.COMMIT
更新对实体的影响 查询的持久化上下文 没有具体说明。public enum FlushModeType { COMMIT, AUTO }
如果没有活动的交易,则 持久性提供程序不得刷新 数据库。
假设您使用AUTO
,请检查交易方。
答案 2 :(得分:0)
在第一种情况下,id是一个Integer
在第二个中,id是一个String
整数永远不会等于字符串