Flyway 和 Spring Boot 集成

Posted

技术标签:

【中文标题】Flyway 和 Spring Boot 集成【英文标题】:Flyway and Spring Boot integration 【发布时间】:2015-05-29 05:29:12 【问题描述】:

我尝试在 Spring Boot 项目中使用 Hibernate 和 Spring JPA 集成 Flyway 以进行迁移。我收到以下异常:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'flyway' 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.FlywayException: Found non-empty schema "PUBLIC" without metadata table! Use init() or set initOnMigrate to true to initialize the metadata table.

我的pom.xml 是这样的:

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

我正在使用 Hibernate 和一个用于 postgres(开发阶段)和 h2(本地)的配置 java 文件。签名看起来像这样:

  @Bean(initMethod = "migrate")
  public Flyway flyway() 
    Flyway fly = new Flyway();
    fly.clean();
    fly.init();
    //flyway.setInitOnMigrate(true);
    fly.setSchemas("SBA_DIALOG");
    //flyway.setLocations("filesystem:src/main/resources/db/migration");
    fly.setDataSource(this.dataSource());
    fly.migrate();
    return fly;
  
@Bean(name = "sbaEntityManagerFactory") @DependsOn("flyway")
  public LocalContainerEntityManagerFactoryBean entityManagerFactory() 
...

我找不到有关此问题中描述的问题的任何信息。 有人可以帮忙吗?

【问题讨论】:

Spring Boot 已经支持 flyway 唯一需要的就是添加 flyway 作为依赖项......我建议阅读 manual 和 configuration properties。对我来说,您似乎正在使用 boot 并非常努力地解决它(例如显式配置所有内容)。 很奇怪:如果你自己配置flyway,spring boot不应该启动flyway自动配置(问题是是否有必要)。但是错误来自启动自动配置。但是尝试将 flyway.initOnMigrate= true 添加到您的 application.properties 并删除您自己的飞行路初始化:) @sodik 实际上我已经在类路径(3.2.1)中飞行,但它不起作用。可能是什么问题? 对我来说,问题是flyway和spring版本不匹配 【参考方案1】:

Spring-Boot 可以自行完成。 只需将 flyway 作为依赖项添加到您的项目中,spring-boot 就会选择它。 Flyway 迁移将在服务启动时开始。

如果您已经在数据库中有一些表,请添加:

spring.flyway.baselineOnMigrate = true 

在您的属性文件中,以在发现某些表已存在时保持 flyway 平静。 ;-)

Flyway 应该获取您的数据源。例如,如果您需要其他用户或类似的东西用于 flyway,您可以设置这些属性:

spring.flyway.url: jdbc:postgresql://$db.host/$db.name
spring.flyway.user: MYUSER
spring.flyway.password: MYPWD

(当然添加你的值!你可以使用 SPEL 来引用其他属性)

更新

请注意:如果您使用集群数据库,您可能会遇到同时启动的多个实例尝试同时执行更新的问题。当表锁不起作用时,这是一个问题,我在使用集群 mariaDB 时发生了这种情况。

【讨论】:

请改用flyway.baseline-on-migrate=trueflyway.initOnMigrate 已弃用。 @SergeiLedvanov 你在说什么?文档说flyway.baselineOnMigrate。 flywaydb.org/documentation/configfiles 我假设那里使用了 config-property-classes 并且它能够处理snake_case、kebab-case和camelCase 使用 spring boot 你使用 spring.flyway.baseline-on-migrate = true 使用 spring.flyway.baselineOnMigrate = true 代替。 flyway.baseline-on-migrate=true 和 flyway.initOnMigrate 已弃用。【参考方案2】:

任何想用java代码解决它的人都可以使用:

fly.setBaselineOnMigrate(true);

编辑(22-09-2020)

另一个解决方案也是:

spring:
  flyway:
    baselineOnMigrate: true
    validateOnMigrate: false

【讨论】:

以上是关于Flyway 和 Spring Boot 集成的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot集成Flyway实现数据库版本控制?

Flyway 与 Spring Boot 的集成不会在嵌入式 H2 数据库上执行迁移脚本

Spring Boot 集成 Flyway,数据库也能做版本控制,太牛逼了!

使用 Flyway 和 Spring Boot 迁移基线

带有用户名和密码的 Zonky + Spring Boot + Postgres + Flyway

将 Flyway 设置为在 Spring Boot 中使用不同的环境