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

Spring项目中H2数据库SQL脚本重复执行问题求助

解决Spring JdbcTest中SQL脚本多次执行的问题

问题原因

你在测试类上标注的@Sql注解,Spring默认会在每个测试方法执行前跑一遍指定的脚本(默认参数executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD)。所以跑整个测试类时,每个测试方法都会触发一次脚本执行;单独跑单个方法时,自然只执行一次。


解决方案

方案1:让脚本只在测试类启动时执行一次

修改@Sql的执行时机为测试类初始化前,同时给测试类加上事务注解,保证每个测试方法结束后自动回滚数据,避免测试方法之间互相污染。

修改后的代码:

@JdbcTest
@Sql(
    scripts = {"sqlFiles/A.sql", "sqlFiles/B.sql", "sqlFiles/C.sql", "sqlFiles/D.sql"},
    executionPhase = Sql.ExecutionPhase.BEFORE_TEST_CLASS
)
@Transactional
@Rollback
class RepositoryTest {

    @Autowired
    DataSource dataSource;
    Repository repository;
    NamedParameterJdbcTemplate jdbcTemplate;


    @BeforeEach
    public void setUp() {
        jdbcTemplate = new NamedParameterJdbcTemplate(dataSource);
        repository = new Repository();
        repository.setJdbcTemplate(jdbcTemplate);
    }

    @Test
    public void findAll() {
        var result = repository.findAll();
        //one data was added for test
        assertEquals(1, result.size());
        assertEquals("OID_1", result.get(0).getOid());
    }

    // 其他测试方法...
}

方案2:让脚本本身支持重复执行(备选)

如果不想改执行时机,可以让SQL脚本本身变成幂等的——比如在每个插入数据的脚本开头,先清空目标表:

-- 在A.sql开头添加
TRUNCATE TABLE your_table RESTART IDENTITY;

这样每次执行脚本都会先清空表,避免重复插入导致数据量不符合预期,但这种方式不如事务回滚高效。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 04:00:10