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

使用H2数据库测试JPA Repository的JUnit无数据返回问题排查

解决方案

1. 移除URL中的INIT配置,利用测试环境自动加载脚本

@DataJpaTest默认会自动加载src/test/resources下的data.sql/schema.sql,无需在数据库URL里通过INIT参数指定脚本路径。在src/test/resources/application.properties中配置:

spring.datasource.url=jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1
spring.jpa.hibernate.ddl-auto=create
spring.jpa.defer-datasource-initialization=true
  • spring.jpa.defer-datasource-initialization=true是核心配置:它会让Spring Boot等Hibernate完成表结构创建后,再执行data.sql的插入语句,避免Hibernate的建表操作覆盖已插入的数据。

2. 处理事务回滚的影响

@DataJpaTest默认给每个测试方法开启事务,测试结束自动回滚,但只要data.sql在事务开启前执行,测试方法内就能查询到数据(事务内可见未提交数据)。开启上述defer-datasource-initialization后,数据会在事务启动前插入,无需额外修改事务配置。

3. 对齐枚举类型与JPA实体定义

确保Encouragement实体中的枚举字段使用@Enumerated(EnumType.STRING),和data.sql里的字符串枚举定义匹配:

@Entity
public class Encouragement {
    @Id
    private Integer id;
    
    @Enumerated(EnumType.STRING)
    private Category category;
    
    // 其他字段、构造方法及getter/setter
}

如果实体用默认的EnumType.ORDINAL(数字枚举),会和手动创建的字符串枚举类型冲突,导致插入失败(注意查看控制台错误日志)。

4. 简化测试代码

@DataJpaTest已包含@ExtendWith(SpringExtension.class),可去掉冗余注解:

@DataJpaTest
class EncouragementRepositoryTest {

    @Autowired
    EncouragementRepository repository;

    @Test
    public void find_all() {
        List<Encouragement> list = repository.findAll();
        assertEquals(33, list.size());
    }
}

5. 验证脚本是否被执行

在data.sql开头添加H2支持的打印语句,确认脚本是否被加载:

PRINT '正在执行data.sql...';
drop TYPE Category if exists;
drop TYPE Tone if exists;
drop TYPE Topic if exists;
drop table ENCOURAGEMENT if exists;
-- 后续创建表及插入语句

启动测试后查看控制台是否有正在执行data.sql...的输出,以此判断脚本是否被触发。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 06:10:30