【问题标题】:JPA: Native Queries does not trigger execution of cached inserts/updates in same transactionJPA:本机查询不会触发在同一事务中执行缓存的插入/更新
【发布时间】:2013-11-01 22:27:42
【问题描述】:

我有一个 JUnit 测试,我在测试用例的开头设置测试数据,然后在相同的测试方法中测试测试用例的条件。测试测试用例条件的查询是本机查询。我知道我必须显式调用 EntityManager.flush() 才能将我的插入/更新立即写入数据库,因为它们在同一个事务中。此外,我注意到我可以用 JPA 查询替换 entityManager.flush(),这似乎可以达到同样的效果。我听说 JPA 会在同一个事务中缓存数据库操作,直到需要立即执行它们,例如发出选择查询时。所以这一切都是有道理的。我的问题是,为什么这种行为也不适用于本机查询?这里我的原生查询不会触发 testSetup() 中插入/更新的立即执行,从而导致我的断言失败。

@Test
@Transactional
public void testCase() {
    testSetup();
    entityManager.flush();  // can be replaced with entityManager.createQuery("from Person");

    List resultList = entityManager.createNativeQuery("select * from Person").getResultList();
    Assert.assertTrue(resultList.size() == 1);
}

【问题讨论】:

    标签: spring jpa junit spring-transactions spring-test


    【解决方案1】:

    tl;dr - 本机查询绕过持久性上下文和缓存。

    这显然包括您通过调用createNativeQuery 创建的查询。但是批量更新(UPDATEDELETE)虽然以 JPQL 表示,但由提供者转换为本地查询,并绕过持久性上下文和缓存。

    因此刷新或执行其他查询不会有预期的效果。

    此外,如果您的本机查询更改了在当前持久性上下文中管理或缓存的实体上的数据,则这些实体将不会自动刷新并且会变得陈旧。

    【讨论】:

      猜你喜欢
      • 2012-03-21
      • 1970-01-01
      • 2018-09-30
      • 2018-08-03
      • 1970-01-01
      • 2018-11-12
      • 1970-01-01
      • 2013-06-11
      • 2021-10-13
      相关资源
      最近更新 更多