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

Spring Boot Gradle项目JUnit5 Repository测试类执行报错求助

问题分析与解决方案

问题根源

  1. ID生成策略冲突:Domain实体的id采用GenerationType.IDENTITY自增策略,但测试代码中手动给实体硬编码id=1。H2内存库的自增序列不会随事务回滚重置,当多个测试方法连续运行时,后续测试中domainRepository.save(domain)生成的实际ID会是2、3...而非手动指定的1。
  2. 关联实体引用错误:createTopic()方法中新建了一个独立的Domain对象并设置id=1,而非使用@BeforeEach中创建的Domain实例。后续测试中,Topic关联的id=1Domain在当前事务中不存在,触发关联查找失败。

修复步骤

1. 移除手动设置ID的代码

因为使用自增策略,无需手动指定ID,让JPA自动生成:

private Domain createDomain() {
  Domain domain = new Domain();
  domain.setName("Java");
  domain.setUid("1234z637-c6c1-4dc3-9755-9f6ad974d70b");
  return domain;
}

private Topic createTopic(Domain domain) { // 接收已创建的Domain实例
  Topic topic = new Topic();
  topic.setName("Java");
  topic.setUid("35f66eaa-2fc7-4170-8470-feb83ddbf6b0");
  topic.setDomain(domain); // 使用传入的Domain实例,保证关联正确性
  return topic;
}

2. 调整测试初始化与保存逻辑

确保Topic关联的是保存后的Domain实例(包含自动生成的ID):

@BeforeEach
void addTestRecord() {
  domain = createDomain();
  topic = createTopic(domain); // 传入domain实例
}

@Test
void findAllTopicByDomainId() {
  // 保存后获取带生成ID的Domain实体
  Domain savedDomain = domainRepository.save(domain);
  // 更新Topic的Domain引用为保存后的实例
  topic.setDomain(savedDomain);
  topicRepository.save(topic);
  
  final var result =
      topicRepository.findAllTopicByDomainId("1234z637-c6c1-4dc3-9755-9f6ad974d70b");
  assertEquals(1, result.size());
  assertEquals("Java", result.get(0).getName());
}

@Test
void deleteByUid() {
  Domain savedDomain = domainRepository.save(domain);
  topic.setDomain(savedDomain);
  topicRepository.save(topic);
  
  assertTrue(topicRepository.findById(topic.getId()).isPresent());
  topicRepository.deleteByUid(topic.getUid());
  assertFalse(topicRepository.findById(topic.getId()).isPresent());
}

@Test
void getTopicByUid() {
  Domain savedDomain = domainRepository.save(domain);
  topic.setDomain(savedDomain);
  topicRepository.save(topic);
  
  final var result = topicRepository.getTopicByUid(topic.getUid());
  assertEquals("Java", result.getName());
}

3. 可选:禁用事务回滚(不推荐)

若不想修改代码,可给测试类添加@Transactional(propagation = Propagation.NOT_SUPPORTED),但此方式会导致测试数据在方法间共享,引发测试耦合,不建议使用。

单独运行测试正常的原因

单独运行时,单个测试方法的事务中,domainRepository.save(domain)生成的ID为1,Topic关联的id=1Domain存在,因此测试通过。连续运行时,H2自增序列不会因事务回滚重置,后续测试生成的Domain ID递增,而Topic仍关联id=1,导致实体查找失败。

内容的提问来源于stack exchange,提问作者Anup Panchal

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 09:41:59