You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot集成测试中数据无法持久化/访问的问题排查

Spring Boot GraphQL集成测试:TestEntityManager保存的数据无法被仓库查询到

问题原因

测试类添加的@Transactional注解会让整个测试方法运行在单一事务上下文中:TestEntityManager.persistFlushFind()保存的数据仅存在于当前事务的缓存里,并未真正提交到数据库。而HttpGraphQlTester发送的GraphQL请求会触发独立的HTTP调用,这个调用会在全新的事务中执行——由于测试事务未提交,新事务无法读取到未提交的数据,因此仓库查询返回空。

解决方案

提供两种可行修复方案:

方案1:移除@Transactional,手动提交事务

移除测试类的事务注解,通过EntityManager手动提交数据,确保数据写入数据库后再发起GraphQL请求:

@SpringBootTest
@AutoConfigureHttpGraphQlTester
@AutoConfigureTestEntityManager
// 移除@Transactional注解
public class BackboneTreeControllerTest {

  @Autowired
  HttpGraphQlTester tester;

  @Autowired
  private TestEntityManager testEntityManager;

  @Autowired
  private EntityManager entityManager;

  @Test
  void findTaxon() {
    Taxon taxon = Taxon.builder()
      .path(Arrays.asList("path", "to", "taxon"))
      .nameCanonical("Cocos nucifera")
      .authorship("Me")
      .extinct(false)
      .numDescendants(1L)
      .numOccurrences(1L)
      .build();

    Taxon savedTaxon = testEntityManager.persistFlushFind(taxon);
    // 手动提交事务,将数据写入数据库
    entityManager.getTransaction().commit();

    this.tester.documentName("queries")
      .operationName("FindTaxon")
      .variable("taxonId", savedTaxon.getId())
      .execute()
      .path("findTaxon.authorship")
      .entity(String.class)
      .isEqualTo("Me");
  }
}

方案2:保留@Transactional,添加@Commit强制提交

保留事务注解,通过@Commit让测试事务在保存数据后直接提交,后续GraphQL请求即可读取到数据:

@SpringBootTest
@AutoConfigureHttpGraphQlTester
@AutoConfigureTestEntityManager
@Transactional
@Commit // 添加该注解,强制提交测试事务
public class BackboneTreeControllerTest {

  @Autowired
  HttpGraphQlTester tester;

  @Autowired
  private TestEntityManager testEntityManager;

  @Test
  void findTaxon() {
    Taxon taxon = Taxon.builder()
      .path(Arrays.asList("path", "to", "taxon"))
      .nameCanonical("Cocos nucifera")
      .authorship("Me")
      .extinct(false)
      .numDescendants(1L)
      .numOccurrences(1L)
      .build();

    Taxon savedTaxon = testEntityManager.persistFlushFind(taxon);

    this.tester.documentName("queries")
      .operationName("FindTaxon")
      .variable("taxonId", savedTaxon.getId())
      .execute()
      .path("findTaxon.authorship")
      .entity(String.class)
      .isEqualTo("Me");
  }
}

补充说明

  • 手动测试时功能正常,是因为手动操作时数据已被提交到数据库,所有请求都能读取到已提交的数据。
  • 若不想污染测试数据库,可在测试方法结束后手动清理数据,或结合@Rollback(注意@Commit会覆盖@Rollback的默认回滚行为)。

内容的提问来源于stack exchange,提问作者m-podolski

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 20:45:15