在测试之间重置 JPA 生成的值

Ryt*_*mic 6 java spring hibernate jpa junit4

我正在使用 springJunit4runner 运行 spring + hibernate + JUnit 并将事务设置为默认回滚 我使用内存中的 derbydb 作为数据库。Hibernate 用作 JPA 提供程序,我正在成功测试 CRUD 类型的东西。但是,我对 JPA 和 @GenerateValue 的行为有疑问

如果我单独运行其中一个测试,则两个实体的 id 为 1 和 2。如果我运行整个测试套件,则 id 为 6 和 7。Spring 可以很好地进行回滚,因此数据库中只有这两个实体加法之后,当然之前为零。但是 @GenerateValue 的行为不允许我可靠地 findById 除非我从

dao.add(Entity e) //method
Run Code Online (Sandbox Code Playgroud)

我不想为了测试而这样做,或者返回被持久化的实体是一个很好的做法,所以我无论如何都应该这样做?

Gol*_*Sky 5

在我们的项目中,我们使用 spring boot 和内存数据库中的 h2 进行测试,我们在测试类上使用以下注释解决了这个问题:

@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD)
Run Code Online (Sandbox Code Playgroud)

例如:

    @RunWith(SpringRunner.class)
    @AutoConfigureMockMvc
    @SpringBootTest(
        webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
        classes = Main.class
    )
    @DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD)
    @TestPropertySource(locations = "classpath:application-test.properties")
    public class FooTest {

    }
Run Code Online (Sandbox Code Playgroud)


Ryt*_*mic 0

我找到了一种方法来做到这一点。手动更改表以重新启动/重置 auto_increment 值。当我使用 Derby DB 时,它是通过以下作为本机查询调用发出的 sql 查询来完成的,因为我如上所述使用 JPA API

em.createNativeQuery("ALTER TABLE konsult ALTER COLUMN id RESTART WITH 1").executeUpdate();
Run Code Online (Sandbox Code Playgroud)

这是不言自明的,但基本上您提供表名称和该表的自动递增列,然后选择应给出第一个持久行的值。

这是使用 mysql 实现的方法: 使用 JPA 重置 MySql 数据库的自增值

我仍然愿意接受其他建议,因为这是一种黑客行为,并且在某种程度上依赖于其他测试。它也不独立于 RDBMS。