1

我有一个带有 Spring 注释的 JUnit 4 测试用例,@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;
}
4

3 回答 3

3

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

更新:原来问题是使用了不正确的事务管理器,因此实体没有被刷新到数据库中。参见帕斯卡的解释。

于 2010-08-05T20:44:41.387 回答
3

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

3.6.2 查询和FlushMode

刷新模式设置对查询结果的影响如下。

当在事务中执行查询时,如果FlushModeType.AUTOQuery对象上设置了 if ,或者如果持久性上下文的刷新模式设置为AUTO(默认)并且没有为Query对象指定刷新模式设置,则持久性提供程序负责确保对持久化上下文中所有实体状态的所有更新,这些更新可能会影响查询的结果,对查询的处理是可见的。持久性提供者实现可以通过将这些实体刷新到数据库或通过其他方式来实现这一点。如果 FlushModeType.COMMIT设置,则未指定对持久性上下文中的实体进行的更新对查询的影响。

public enum FlushModeType {
    COMMIT,
    AUTO
}

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

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

于 2010-08-05T21:36:38.190 回答
0

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

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

整数永远不会等于字符串

于 2010-08-05T19:04:34.617 回答