繁体   English   中英

为什么在JPA中通过id找到一个对象,而通过JPQL查询却找不到呢?

[英]Why is an object found by id in JPA, but not through a JPQL query?

我有一个带有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;
}

实体处于当前会话(实体管理器)中-处于持久状态,等待刷新。 get方法首先检查会话的内容,如果找不到,则转到基础数据库。 在您的情况下,实体刚刚保存在同一会话中,因此找到并返回了该实体。

更新:原来问题出在使用不正确的事务管理器,因此该实体尚未刷新到数据库。 请参阅Pascal的说明。

如果使用的是默认刷新模式( AUTO ),并且正在事务中执行查询,则JPA规范保证查询不会返回陈旧或不正确的数据:

3.6.2查询和FlushMode

刷新模式设置会影响查询结果,如下所示。

当查询在事务内执行,如果FlushModeType.AUTO被设定在上Query对象,或者如果在冲洗模式设置为持久性上下文是AUTO (缺省值)和冲刷模式设置尚未指定的Query对象时,持久性提供程序负责确保对持久性上下文中所有实体状态的所有更新(可能会影响查询结果)对于查询的处理都是可见的。 持久性提供程序实现可以通过将这些实体刷新到数据库或通过其他某种方式来实现。 如果设置了FlushModeType.COMMIT ,则未指定在持久性上下文中对查询进行的实体更新的影响。

 public enum FlushModeType { COMMIT, AUTO } 

如果没有活动的事务,则持久性提供程序不得刷新到数据库。

假设您正在使用AUTO ,请检查事务处理方面。

在第一种情况下,id是一个整数

在第二个中,id是一个字符串

整数永远不会等于字符串

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM