为什么一个目标是通过ID在JPA发现,但不是通过JPQL查询?
题
我有一个JUnit 4测试用例与Spring @Transactional
注释,节省的对象,然后尝试找到它。测试用例通过当我使用这个实现:
@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;
}
解决方案
如果您使用的是默认刷新模式(AUTO
),如果你是在一个事务中执行查询时,JPA规范保证查询不会返回过期或不正确的数据:
3.6.2查询和FlushMode
在刷新模式设置影响 查询的结果如下:
当查询内的执行 交易,如果
FlushModeType.AUTO
被设定在Query
对象上,或者如果 冲洗模式设置为持久性 上下文是AUTO
(默认值)和一个 洗净模式设置尚未 为Query
对象指定, 持久性提供者负责 确保所有更新到 在所有实体的状态 持久化上下文可能 潜在地影响的结果 查询是加工可见 查询。持久性提供程序 实现可以通过实现这一目标 冲洗这些实体的 数据库或通过一些其它手段。如果FlushModeType.COMMIT
被设置, 更新的效果中的实体做出 在查询持久化上下文 是不确定的。public enum FlushModeType { COMMIT, AUTO }
如果没有事务活动的,则 持久性提供者不得平齐 数据库中。
假设使用的是AUTO
,检查事务侧。
其他提示
Тhe实体是在当前会话(实体管理器) - 它是在持久状态,等待被冲洗。 get方法首先检查会话的内容,如果没有发现轮流基础数据库。在你的情况下,实体刚刚被保存在同一个会议上,所以它找到并归还。
更新:它原来的问题是使用了不正确的事务管理器,因此该实体还没有被刷新到数据库。见帕斯卡的解释。
在第一种情况下,该ID是一个整
在第二,该ID是一个字符串
整数永远等于一个String
不隶属于 StackOverflow