首页 > 解决方案 > Spring ScriptUtils:使用 MySql 导致测试永远冻结

问题描述

我正在尝试根据 Spring Boot 测试环境中的活动配置文件(h2 或 mysql)执行不同的 sql 脚本。这是我尝试使用 MySql 执行的导致冻结的测试用例:

@RunWith(SpringRunner.class)
@DataJpaTest
@AutoConfigureTestDatabase(replace= AutoConfigureTestDatabase.Replace.NONE)
public class EntityRepositoryTestIT {

    @Autowired
    EntityRepository entityRepository;

    @Autowired
    private DataSource dataSource;

    @Value("${spring.profiles.active}")
    private String profile;

    @After
    public void after() throws Exception {
        ScriptUtils.executeSqlScript(dataSource.getConnection(),
                new ClassPathResource("/scripts/test_data_clear_"+profile+".sql"));
    }


    @Test
    @Sql(scripts = "/scripts/test_data.sql", executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD)
    public void findAllTest() throws Exception {
        Assert.assertEquals(7, entityRepository.findAll().size());
    }

}

org.springframework.jdbc 上启用 DEBUG 的记录器显示在调用此行时发生冻结:

ALTER TABLE entity AUTO_INCREMENT = 1;

这仅在 MySql 中失败,而在 H2 中可以正常工作:

ALTER TABLE entity ALTER COLUMN id RESTART WITH 1;

通过使用注释,测试再次与 MySql 一起正常工作:

@Sql(scripts = "/scripts/test_data_clear_mysql.sql", executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD)

似乎@sql 注释比 ScriptUtils 的编程调用添加了更多逻辑。使用 H2,ScriptUtils 和 @sql 注释都可以顺利工作。

问题是注解不允许动态改变执行的sql脚本,它的'scripts'参数是一个编译时间常数。

任何有关如何使其工作的建议将不胜感激!

标签: javamysqlspring

解决方案


我的直觉是您根本没有正确关闭/返回数据库连接。

@After
public void after() throws Exception {
    try (Connection connection = dataSource.getConnection()) {
        if (connection != null) {
            ScriptUtils.executeSqlScript(connection,
                new ClassPathResource("/scripts/test_data_clear_"+profile+".sql"));
            log.info("SQL script successful");
        } else {
            log.warn("!!! No connection available !!!");
        }
    }
}

即,将您的连接包装在一个try-catch-resources块中,以便关闭连接(如果您使用数据库池,例如 Hikari,则将其返回到池中)。


推荐阅读