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

Spring测试中@Sql注解失效问题排查求助

解决@DataJpaTest中@Sql注解未生效的问题

我之前也碰到过一模一样的情况——用@DataJpaTest时data.sql能正常加载,但专门指定@Sql脚本却死活不生效。下面是我踩坑后总结的排查和解决方法:

1. 先确认@Sql的路径是否正确

这是最常见的问题!@Sql默认是相对于测试类的包路径来查找脚本的,如果你把SQL文件放在src/test/resources根目录下,必须用绝对路径指定:

// 正确写法:用classpath前缀或者直接以/开头
@Sql("classpath:/test-specific-data.sql")
// 或者更简洁的写法(Spring会自动识别classpath)
@Sql("/test-specific-data.sql")

举个例子:如果你的测试类在com.example.repositorytest包下,而SQL文件在resources/sql/test-data.sql,那路径要写成@Sql("/sql/test-data.sql")。

2. 检查事务回滚导致的“假失效”

@DataJpaTest默认会给测试方法加上@Transactional,测试结束后会自动回滚事务。如果你的@Sql脚本是在测试事务内执行的,脚本插入的数据会跟着事务一起回滚,导致你在测试里看不到数据。

解决方法是让脚本在独立事务中执行:

@Sql(
    scripts = "/test-specific-data.sql",
    config = @SqlConfig(transactionMode = SqlConfig.TransactionMode.ISOLATED)
)

这样脚本会在单独的事务里运行,不会被测试的回滚影响。

3. 排除默认data.sql的干扰

如果你同时存在data.sql,它会被@DataJpaTest自动加载,可能和你的@Sql脚本冲突,或者覆盖你想要的初始化数据。如果只想让@Sql脚本生效,可以禁用默认的data加载:

@DataJpaTest
@TestPropertySource(properties = {
    "spring.sql.init.data-locations=none" // 关闭默认data.sql加载
})
@Sql("/test-specific-data.sql")
public class MyRepoTest {
    // ...
}

4. 查看日志排查执行细节

如果上面的方法都没用,开启日志看看脚本到底有没有被加载执行。在src/test/resources/application-test.properties里添加:

logging.level.org.springframework.jdbc.datasource.init=DEBUG
logging.level.org.springframework.test.context.jdbc=DEBUG

运行测试后,你可以在日志里看到:

  • 脚本是否被找到
  • 执行过程中有没有SQL语法错误
  • 脚本执行的时机是否符合预期

5. 确认@Sql的执行时机

默认@Sql是在测试方法执行前运行(BEFORE_TEST_METHOD),如果你的测试逻辑需要在其他时机加载数据,可以调整executionPhase:

// 在测试类初始化前执行脚本
@Sql(
    scripts = "/test-data.sql",
    executionPhase = Sql.ExecutionPhase.BEFORE_TEST_CLASS
)

示例完整代码

@DataJpaTest
@TestPropertySource(properties = {
    "spring.sql.init.data-locations=none"
})
@Sql(
    scripts = "/test-specific-data.sql",
    config = @SqlConfig(transactionMode = SqlConfig.TransactionMode.ISOLATED)
)
public class UserRepositoryTest {

    @Autowired
    private UserRepository userRepository;

    @Test
    void shouldFindUserFromSqlScript() {
        Optional<User> user = userRepository.findByUsername("test-user");
        assertThat(user).isPresent();
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 09:12:52