Spring Boot 2.1.0 с Flyway 4.2.0 - PullRequest
       11

Spring Boot 2.1.0 с Flyway 4.2.0

0 голосов
/ 16 ноября 2018

Я бы хотел обновить свои новые проекты до версии Spring Boot 2.1.0, но я ограничен базой данных Oracle 11, которая поддерживается библиотекой Flyway 4.2.0 .В 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;
}

Ответы [ 3 ]

0 голосов
/ 04 декабря 2018

Я сделал конфигурацию для Spring Boot 2.1.1, и мне также пришлось переопределить компонент 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");
        }

    }
}
0 голосов
/ 14 июня 2019

Используя библиотеку Javassist, вы можете настроить библиотеку FlywayDB для регистрации того, что версия Oracle больше не поддерживается, вместо того, чтобы выдавать неустранимое исключение (заключая вызов метода sureDatabaseIsCompatibleWithFlywayEdition в предложение try-catch).В моем случае редакция сообщества 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);
    }
}
0 голосов
/ 16 ноября 2018

У меня была та же проблема с 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.

...