在内存数据库中使用H2进行Spring测试会截断所有表

时间:2016-08-17 11:55:30

标签: java mysql spring spring-mvc h2

我是一名使用春天从事MVC项目的初级CS专业学生,我对春天很新。

我在内存db中设置了H2并编写了2个sql脚本;一个填充数据库,另一个填充空。

据我所知,truncate table <table name>delete from <table name>之间的实际区别是截断表是ddl因此它更快,它也会重置自动增量列。问题是H2的truncate table没有重置自动递增的列。你能指出我搞砸了吗?

我使用spring的SqlGroup注释来运行脚本。

@SqlGroup({
    @Sql(executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD, scripts = 
                                                "classpath:populate.sql"),
    @Sql(executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD, scripts = 
                                                  "classpath:cleanup.sql")
})

这里是应该截断每个表的cleanup.sql。

SET FOREIGN_KEY_CHECKS=0;

TRUNCATE TABLE `criteria`;
TRUNCATE TABLE `job_title`;
TRUNCATE TABLE `organization`;
TRUNCATE TABLE `organization_teams`;
TRUNCATE TABLE `organization_users`;
TRUNCATE TABLE `organization_job_titles`;
TRUNCATE TABLE `review`;
TRUNCATE TABLE `review_evaluation`;
TRUNCATE TABLE `team`;
TRUNCATE TABLE `team_members`;
TRUNCATE TABLE `user`;
TRUNCATE TABLE `user_criteria_list`;

SET FOREIGN_KEY_CHECKS=1;

populate.sql只是在不违反完整性约束的情况下向这些表插入一堆行。

所以当我运行我的测试类时,只有第一个方法通过。其余的我得到这样的东西:

参照完整性约束违规:&#34; FK3MAB5XYC980PSHDJ3JJ6XNMMT:PUBLIC.ORGANIZATION_JOB_TITLES FOREIGN KEY(JOB_TITLES_ID)参考PUBLIC.JOB_TITLE(ID)(1)&#34 ;; SQL语句: INSERT INTO organization_job_titles(organization_id,job_titles_id)VALUES(1,1)

我认为问题是由于自动递增的列未被重置而产生的。所以我写了一个不同的测试类:

monAutoIncTest.java

 @Sql(executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD, scripts =
    "classpath:truncateTable.sql")
    public class monAutoIncTest {
        @Autowired
        OrganizationService organizationService;

        @Test
            public void h2truncate_pls() throws BaseException {
            organizationService.add(new Organization("Doogle"));
            Organization fetched = organizationService.getByName("Doogle");
            Assert.assertEquals(1, fetched.getId());
        }

        @Test
        public void h2truncate_plz() throws BaseException {
            organizationService.add(new Organization("Zoogle"));
            Organization fetched = organizationService.getByName("Zoogle");
            Assert.assertEquals(1, fetched.getId());
        }
    } 

使用truncateTable.sql

SET FOREIGN_KEY_CHECKS=0;

TRUNCATE TABLE `organization`;

SET FOREIGN_KEY_CHECKS=1;

当测试运行时,无论哪个方法首先运行,另一个方法都会给我这个。

java.lang.AssertionError: 预期:1 实际:2

2 个答案:

答案 0 :(得分:2)

目前H2不支持该功能,但我们可以在their roadmap

中看到此类计划
  

TRUNCATE应该重置MySQL和MS SQL中的标识列   服务器(可能还有其他数据库)。

尝试在TRUNCATE的作文中使用此声明:

ALTER TABLE [table] ALTER COLUMN [column] RESTART WITH [initial value]

答案 1 :(得分:0)

对于每个表名,执行SQL脚本:

TRUNCATE TABLE my_table RESTART IDENTITY;
ALTER SEQUENCE my_table_id_seq RESTART WITH 1;

H2的版本应为1.4.200或更高版本。

请参见https://www.h2database.com/html/commands.html