【问题标题】:Flyway migration error details with Spring Boot使用 Spring Boot 的 Flyway 迁移错误详细信息
【发布时间】:2021-06-12 21:24:04
【问题描述】:

我们有一个使用 Spring Boot 和 flyway 的项目。

当我们运行迁移失败且日志级别全部设置为 DEBUG 时,我们只收到以下消息:

[DEBUG] org.flywaydb.core.internal.command.DbValidate - Validating migrations ...
[DEBUG] org.flywaydb.core.internal.scanner.Scanner - Filtering out resource: db/migration/V1/V1_202103081030__account.sql (filename: V1_202103081030__account.sql)
[DEBUG] org.flywaydb.core.internal.scanner.Scanner - Filtering out resource: db/migration/V1/V1_202103081040__place.sql (filename: V1_202103081040__place.sql)
[DEBUG] org.flywaydb.core.internal.scanner.Scanner - Filtering out resource: db/migration/V1/V1_202103151608__document.sql (filename: V1_202103151608__document.sql)
[DEBUG] org.flywaydb.core.Flyway - Memory usage: 147 of 254M
[ERROR] org.springframework.boot.web.embedded.tomcat.TomcatStarter - Error starting Tomcat context. Exception: org.springframework.beans.factory.UnsatisfiedDependencyException. Message: Error creating bean with name 'webSecurityConfig': Unsatisfied dependency expressed through method 'setContentNegotationStrategy' parameter 0; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration$EnableWebMvcConfiguration': Unsatisfied dependency expressed through method 'setConfigurers' parameter 0; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'openEntityManagerInViewInterceptorConfigurer' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/JpaBaseConfiguration$JpaWebConfiguration.class]: Unsatisfied dependency expressed through method 'openEntityManagerInViewInterceptorConfigurer' parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'openEntityManagerInViewInterceptor' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/JpaBaseConfiguration$JpaWebConfiguration.class]: Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'flywayInitializer' defined in class path resource [org/springframework/boot/autoconfigure/flyway/FlywayAutoConfiguration$FlywayConfiguration.class]: Invocation of init method failed; nested exception is org.flywaydb.core.api.exception.FlywayValidateException: Validate failed: Migrations have failed validation
...
[INFO ] org.apache.catalina.core.StandardService - Stopping service [Tomcat]
...
Caused by: org.flywaydb.core.api.exception.FlywayValidateException: Validate failed: Migrations have failed validation

没有关于失败原因的更多详细信息(失败的查询、不匹配的校验和......)。

我查看了spring.flyway 应用程序属性,但在这里没有发现任何帮助。

我们应该怎么做才能在服务器启动时在我们的日志中显示 flyway root 错误?

编辑:要清楚,问题不在于故障本身(在 Flyway 类中设置断点可以揭示源错误)。问题是日志中缺少错误详细信息。

【问题讨论】:

  • 恕我直言,您的文件名不符合 Flyway 约定。 flywaydb.org/documentation/concepts/migrations
  • 迁移运行顺利,不是这样。事实上,我们知道问题是校验和失败,但我们希望在日志中看到它,以防将来发生我们不知道问题所在的情况。

标签: spring spring-boot flyway


【解决方案1】:

我遇到了同样的问题,发现它与我使用的 Flyway 版本有关(Spring Boot 2.4.3,它使用 Flyway 7.1.1)。这是一个已知问题 2987 - Display all validate messages in exceptions,已在 Flyway 7.2.0 中修复。

他们建议运行flyway validate -outputType=json 作为一种解决方法,以获得详细的错误消息。我试过了,但仍然没有收到详细的错误消息。

对我有用的解决方案是升级到 Flyway 7.2.0,方法是在我的 pom 文件中指定版本:

<dependency>
    <groupId>org.flywaydb</groupId>
    <artifactId>flyway-core</artifactId>
    <version>7.2.0</version>
</dependency>

【讨论】:

    【解决方案2】:

    我不知道具体是什么失败了,但这可能有助于为您指明正确的方向。

    1. 打开 DbValidate(flyway 类)。 (如果需要,请下载源代码)
    2. 在第 186-187 行的 else 语句中放置一个断点
    3. 再次启动服务器

    这至少会告诉你哪个文件失败了。

    然后,您可以向 Flyway 项目提出增强请求,以获得更好的错误报告。

    【讨论】:

    • 公平地说,我们知道问题出在哪里(这里是校验和失败)。问题是我们希望在日志中看到它,以防将来出现我们不知道问题所在的情况。
    • 这很奇怪。当飞行路径迁移发生变化时,我在我们的日志中看到校验和错误。您使用的是什么版本的 Flyway?
    • 根据日志,Spring 包含 7.1.1。我们在其他项目中使用flyway时也会看到校验和错误,我们自己处理,所以我猜这是Spring/Flyway配置的问题。
    • 我们使用的是 Flyway 6.0.8。可能是 Flyway 的回归。提出问题? github.com/flyway/flyway/issues
    【解决方案3】:

    嗯,可能会发生很多事情,但一个可能的原因是您在应用迁移文件后更改了它。我将通过用例进行解释:

    假设在时间 X,您有 2 个迁移(技术上在 SQL 文件中实现):A1 和 A2。

    这是您对 A1 和 A2 的第一次提交,当您运行应用程序时,flyway 在数据库中创建一个特殊表,以查看已应用哪些迁移。显然,在时间 X 还没有迁移,所以它创建一个表,应用 A1 和 A2,并在表中添加 2 条记录。除其他事项外,这些记录应包括校验和。简单来说,你可以把这些校验和看作是 A1 和 A2 的内容对应的哈希值(如 sha1)。

    到目前为止一切顺利,现在当您引入新的迁移文件 A3 时,时间快进(到时间 Y)。

    当您重新部署应用程序时,flyway 会检查已应用的 A1 和 A2 是否没有更改,然后才会应用新的迁移。

    现在,此验证实际上是应用迁移 A3 检查这些哈希值的先决条件 - 校验和。这是合理的——因为如果你碰巧改变了 A1 或 A2——flyway 应该怎么做——它如何保证迁移按预期工作?

    您也可以阅读 in the official flyway documentation 关于此验证的信息,但是,您明白我相信的想法。有人通过更改您现有的迁移之一更改了校验和,并试图重新部署应用程序。

    简单地说,一旦应用了迁移文件 - 就不能在源代码树中更改它

    现在我描述的场景是一种可能的场景,一般来说,您甚至不必创建迁移 A3,只需更改现有迁移并尝试重新运行应用程序 - 验证会失败。

    【讨论】:

    • 我的问题应该更准确:问题不在于故障本身(设置断点会显示校验和失败,因为应用后脚本已更改),问题是缺少错误详细信息日志。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-08-07
    • 2020-05-09
    • 1970-01-01
    • 2018-08-16
    • 2018-10-07
    • 1970-01-01
    • 2020-07-17
    相关资源
    最近更新 更多