Flyway 没有正确清理数据库,执行了两次迁移文件

Posted

技术标签:

【中文标题】Flyway 没有正确清理数据库,执行了两次迁移文件【英文标题】:Flyway don't clean database correctly, and execute migration files two times 【发布时间】:2020-12-30 16:21:33 【问题描述】:

我使用 flyway 进行迁移数据库,我也使用 FlywayTest 进行集成测试,但是当我使用以下方法创建测试时:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = APPApplication.class)
@Rollback
@TestExecutionListeners(DependencyInjectionTestExecutionListener.class, FlywayTestExecutionListener.class)
@FlywayTest
public class RolesRepositoryTest 
   ...

我收到此错误:

o.f.c.internal.license.VersionPrinter    : Flyway Community Edition 6.0.8 by Redgate
com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
o.f.c.internal.database.DatabaseFactory  : Database: jdbc:h2:mem:testdb (H2 1.4)
o.f.c.internal.database.base.Database    : Flyway upgrade recommended: H2 1.4.200 is newer than this version of Flyway and support has not been tested. The latest supported version of H2 is 1.4.199.
o.f.core.internal.command.DbValidate     : Successfully validated 4 migrations (execution time 00:00.055s)
o.f.c.i.s.JdbcTableSchemaHistory         : Creating Schema History table "PUBLIC"."flyway_schema_history" ...
o.f.core.internal.command.DbMigrate      : Current version of schema "PUBLIC": << Empty Schema >>
o.f.core.internal.command.DbMigrate      : Migrating schema "PUBLIC" to version 1 - CREATE FIRST TABLES
o.f.core.internal.command.DbMigrate      : Migrating schema "PUBLIC" to version 2 - INSERT ROLES
o.f.core.internal.command.DbMigrate      : Migrating schema "PUBLIC" to version 3 - INSERT ADMINS
o.f.core.internal.command.DbMigrate      : Migrating schema "PUBLIC" to version 4 - INSERT OTHERS
o.f.core.internal.command.DbMigrate      : Successfully applied 4 migrations to schema "PUBLIC" (execution time 00:00.464s)
o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]

o.f.test.FlywayTestExecutionListener     : ---> Start reset database for  'com.name.project.infrastructure.database.jpa.RolesRepositoryTest'.
o.f.c.internal.database.base.Database    : Flyway upgrade recommended: H2 1.4.200 is newer than this version of Flyway and support has not been tested. The latest supported version of H2 is 1.4.199.
o.f.core.internal.command.DbClean        : Successfully cleaned schema "PUBLIC" (execution time 00:00.010s)
o.f.c.internal.database.base.Database    : Flyway upgrade recommended: H2 1.4.200 is newer than this version of Flyway and support has not been tested. The latest supported version of H2 is 1.4.199.
o.f.core.internal.command.DbValidate     : Successfully validated 4 migrations (execution time 00:00.023s)
o.f.c.i.s.JdbcTableSchemaHistory         : Creating Schema History table "PUBLIC"."flyway_schema_history" ...
o.f.core.internal.command.DbMigrate      : Current version of schema "PUBLIC": << Empty Schema >>
o.f.core.internal.command.DbMigrate      : Migrating schema "PUBLIC" to version 1 - CREATE FIRST TABLES
o.f.core.internal.command.DbMigrate      : Migration of schema "PUBLIC" to version 1 - CREATE FIRST TABLES failed! Please restore backups and roll back database and code!
o.s.test.context.TestContextManager      : Caught exception while invoking 'beforeTestClass' callback on TestExecutionListener [org.flywaydb.test.FlywayTestExecutionListener@797b0699] for test class [class com.name.project.infrastructure.database.jpa.RolesRepositoryTest]

org.flywaydb.core.internal.command.DbMigrate$FlywayMigrateException: 
Migration V1__CREATE_FIRST_TABLES.sql failed
--------------------------------------------
SQL State  : 42S01
Error Code : 42101
Message    : Table "ROLES" already exists; SQL statement:

如果你没有:

---> Start reset database for  'com.name.project.infrastructure.database.jpa.RolesRepositoryTest'.

这来自FlywayTestExecutionListener.class,但它再次迁移数据库。

为什么flyway会这样做,如何阻止它。

更多详情

当我不在我的表中使用模式名称时,问题不会发生。一切正常。

【问题讨论】:

【参考方案1】:

如果您在每次测试中都重复使用FlywayTestExecutionListener,那么设置将在每个带有@TestExecutionListeners 的类中执行,即使您使用beforeTestClass

在 JUnit 中,为一组测试一次性设置资源的一种方法是定义 Rule(用于 Unit 4)和 Extensions(用于 JUnit 5)。

【讨论】:

我遇到了架构问题,当我从脚本中删除架构时,一切正常,谢谢您的回答,也许它可以在将来帮助我

以上是关于Flyway 没有正确清理数据库,执行了两次迁移文件的主要内容,如果未能解决你的问题,请参考以下文章

使用 Maven + Flyway 迁移/清理/等多个数据库

清洁后无法启动或迁移的flyway

flyway:每次迁移后运行的通用脚本

Flyway:如何支持清理具有相同生命周期的多个模式?

Flyway数据库版本控制与数据迁移工具

Flyway 迁移的最长执行时间