带Flyway 4.2.0的Spring Boot 2.1.0

时间:2018-11-16 18:30:30

标签: java spring-boot flyway

我想将我的新项目升级到Spring Boot版本2.1.0,但是我受限于 Flyway 4.2.0 库支持的Oracle 11数据库。一切都可以在Spring Boot 2.0.5版本上正常运行,但是当移至 2.1.0 版本时,出现此错误:

java.lang.NoClassDefFoundError: 
org/flywaydb/core/api/configuration/FluentConfiguration

POM配置如下:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.1.0.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <java.version>1.8</java.version>
    <ojdbc6.version>11.2.0.1</ojdbc6.version>
</properties>

<dependencies>
    <dependency>
        <groupId>com.oracle.jdbc</groupId>
        <artifactId>ojdbc6</artifactId>
        <version>${ojdbc6.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
        <scope>runtime</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    <dependency>
        <groupId>org.flywaydb</groupId>
        <artifactId>flyway-core</artifactId>
        <version>4.2.0</version>
    </dependency>
</dependencies>

更新

我可以通过@Configuration解决问题(或者当然可以添加到主类中),但问题是它的错误或功能?在2.1.0版之前,所有操作都是通过自动配置完成的,并且可以直接使用。

@Bean(initMethod = "migrate")
Flyway flyway() {
    Flyway flyway = new Flyway();
    flyway.setBaselineOnMigrate(true);
    flyway.setDataSource("jdbc:oracle:thin:@localhost:1521:xe", "USER", "PASSWORD1");
    return flyway;
}

4 个答案:

答案 0 :(得分:1)

我在PostgreSQL 9.2上遇到了同样的问题,并使用下面的类来解决该问题。

请注意,尽管您在Spring Boot属性中可能设置的所有自定义属性都将被忽略,因为这会自己替换整个Flyway自动配置。因此,您可能必须添加一些其他代码以满足您的需求。

@Configuration
class FlywayConfig {
    @Bean
    fun flyway(dataSource: DataSource): Flyway {
        val flyway = Flyway()
        flyway.dataSource = dataSource
        return flyway
    }

    @Bean
    fun flywayInitializer(flyway: Flyway): FlywayMigrationInitializer {
        return FlywayMigrationInitializer(flyway, null)
    }

    /**
     * Additional configuration to ensure that [EntityManagerFactory] beans depend on the
     * `flywayInitializer` bean.
     */
    @Configuration
    class FlywayInitializerJpaDependencyConfiguration : EntityManagerFactoryDependsOnPostProcessor("flywayInitializer")
}

PS:这是Kotlin代码,但是您应该能够轻松地将其转换为Java。

答案 1 :(得分:1)

我为Spring Boot 2.1.1进行了配置,还不得不重新定义bean FlywayDefaultDdlModeProvider。

@Configuration
@ConditionalOnProperty(prefix = "spring.flyway", name = "enabled", matchIfMissing = true)
public class LegacyFlywayAutoConfiguration {

    @Bean
    @Primary
    public SchemaManagementProvider flywayDefaultDdlModeProvider(ObjectProvider<Flyway> flyways) {
        return new SchemaManagementProvider() {
            @Override
            public SchemaManagement getSchemaManagement(DataSource dataSource) {
                return SchemaManagement.MANAGED;
            }
        };
    }

    @Bean(initMethod = "migrate")
    public Flyway flyway(DataSource dataSource) {
        Flyway flyway = new Flyway();
        flyway.setBaselineOnMigrate(true);
        flyway.setDataSource(dataSource);
        return flyway;
    }

    @Bean
    public FlywayMigrationInitializer flywayInitializer(Flyway flyway) {
        return new FlywayMigrationInitializer(flyway, null);
    }

    /**
     * Additional configuration to ensure that {@link JdbcOperations} beans depend
     * on the {@code flywayInitializer} bean.
     */
    @Configuration
    @ConditionalOnClass(JdbcOperations.class)
    @ConditionalOnBean(JdbcOperations.class)
    protected static class FlywayInitializerJdbcOperationsDependencyConfiguration
            extends JdbcOperationsDependsOnPostProcessor {

        public FlywayInitializerJdbcOperationsDependencyConfiguration() {
            super("flywayInitializer");
        }

    }
}

答案 2 :(得分:1)

使用以下依赖项,即可解决此问题。

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

答案 3 :(得分:0)

使用Javassist库,您可以检测FlywayDB库以记录不再受支持的Oracle版本,而不是引发致命异常(通过在try-catch子句中包装sureDatabaseIsCompatibleWithFlywayEdition方法调用)。以我为例,一旦我完成了FlywayDB社区版(5.2.4)的工作,就可以在Oracle 11.2上正常工作。该解决方案有其缺点,但是对于我来说,这是最好的选择(数据库应尽快升级),因此也许有人也会觉得它有用。理想情况下,以下代码应在您的应用程序中运行。 使用后果自负。

public static void suppressIncompatibleDatabaseVersionCheck() {
    try {
        CtClass ctClass = ClassPool.getDefault().get("org.flywaydb.core.internal.database.base.Database");
        ctClass.defrost();
        CtMethod method = ctClass.getDeclaredMethod("ensureDatabaseIsCompatibleWithFlywayEdition");
        CtClass etype = ClassPool.getDefault().get("java.lang.Exception");
        method.addCatch("{ LOG.warn(\"Exception suppressed: \" + $e); return ;}", etype);
        ctClass.toClass();
    } catch (NotFoundException | CannotCompileException e) {
        log.error("Could not instrument FlywayDB code.", e);
    }
}