Flyway for Existing PUBLIC schema

2019-09-16 05:24发布

问题:

    @Configuration
    @ComponentScan("com.sammy")
    @EnableTransactionManagement
    public class DataSourceConfig {

        @Bean(destroyMethod = "shutdown")
        public DataSource dataSource(){
            EmbeddedDatabaseBuilder databaseBuilder = new EmbeddedDatabaseBuilder();
            databaseBuilder.setType(EmbeddedDatabaseType.H2);
            databaseBuilder.addScript("classpath:db/migration/V1__Create_Books_Table.sql");
            databaseBuilder.addScript("classpath:db/migration/V2__Add_Books.sql");
            return databaseBuilder.build();
        }

        @Bean(name = "entityManagerFactory")
        public EntityManagerFactory managerFactory(){
            HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
            vendorAdapter.setGenerateDdl(true);

            Properties jpaProperties = new Properties();
            jpaProperties.put("hibernate.hbm2ddl.auto", "create-drop");
            jpaProperties.put("hibernate.dialect", "org.hibernate.dialect.HSQLDialect");

            LocalContainerEntityManagerFactoryBean managerFactoryBean = new LocalContainerEntityManagerFactoryBean();
            managerFactoryBean.setDataSource(dataSource());
            managerFactoryBean.setPackagesToScan("com.sammy");
            managerFactoryBean.setJpaVendorAdapter(vendorAdapter);
            managerFactoryBean.setJpaProperties(jpaProperties);
            managerFactoryBean.afterPropertiesSet();
            return managerFactoryBean.getObject();
        }

        @Bean
        public PlatformTransactionManager transactionManager(){
            JpaTransactionManager transactionManager = new JpaTransactionManager();
            transactionManager.setEntityManagerFactory(managerFactory());
            return transactionManager;
        }
    }

Above is my data configuration class.

    buildscript {

    repositories {
        jcenter()
        maven {
            url "https://plugins.gradle.org/m2/"
        }
    }
    dependencies {
        classpath "gradle.plugin.com.boxfuse.client:flyway-release:${flywayVersion}"
        classpath "org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:${sonarVersion}"
        classpath "org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}"
    }
}

apply plugin: 'java'
apply plugin: 'jacoco'
apply plugin: 'org.sonarqube'
apply plugin: 'org.flywaydb.flyway'
apply plugin: 'org.springframework.boot'

sourceCompatibility = 1.8
targetCompatibility = 1.8

repositories {
    mavenCentral()
}

jar{
    group 'com.sammy'
    version '1.0-SNAPSHOT'
}

dependencies {

    testCompile "junit:junit:${junitVersion}"
    testCompile "info.cukes:cucumber-java:${cucumberVersion}"
    testCompile "info.cukes:cucumber-junit:${cucumberVersion}"
    //testCompile "info.cukes:cucumber-spring:${cucumberVersion}"
    testCompile 'org.springframework.boot:spring-boot-starter-test'

    compile 'com.h2database:h2'
    compile "org.flywaydb:flyway-core:${flywayVersion}"
    compile "org.projectlombok:lombok:${lombokVersion}"
    compile("org.springframework.boot:spring-boot-starter-web") {
        exclude module: "spring-boot-starter-tomcat"
    }
    compile 'org.springframework.boot:spring-boot-starter-aop'
    compile 'org.springframework.boot:spring-boot-starter-jetty'
    compile "io.springfox:springfox-swagger2:${swaggerVersion}"
    compile "io.springfox:springfox-swagger-ui:${swaggerVersion}"
    compile 'org.springframework.boot:spring-boot-starter-actuator'
    compile 'org.springframework.cloud:spring-cloud-starter-config'
    compile 'org.springframework.boot:spring-boot-starter-data-jpa'
    //compile 'org.springframework.boot:spring-boot-starter-data-mongodb'
}

flyway{
    user = 'sa'
    schema = ['PUBLIC', 'testdb']
    url = 'jdbc:h2:mem:testdb'
    baselineVersion = 7.0
    baselineOnMigrate = false
    baselineDescription = "Base Migration"
}

flywayMigrate{
    dependsOn flyway
}

task wrapper(type :Wrapper){
    gradleVersion = '3.4.1'
}

I have got that build.gradle file which attempts to configure flyway for use within a SpringBoot application. I'm trying to migrate data to an in-memory H2 database but keep getting the error below:

Exception in thread "main" 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.FlywayException: Found non-empty schema(s) "PUBLIC" without metadata table! Use baseline() or set baselineOnMigrate to true to initialize the metadata table.
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1628)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:555)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:761)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:866)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:542)
    at org.springframework.context.annotation.AnnotationConfigApplicationContext.<init>(AnnotationConfigApplicationContext.java:84)
    at com.sammy.SpringDataTutorials.main(SpringDataTutorials.java:18)
Caused by: org.flywaydb.core.api.FlywayException: Found non-empty schema(s) "PUBLIC" without metadata table! Use baseline() or set baselineOnMigrate to true to initialize the metadata table.
    at org.flywaydb.core.Flyway$1.execute(Flyway.java:954)
    at org.flywaydb.core.Flyway$1.execute(Flyway.java:930)
    at org.flywaydb.core.Flyway.execute(Flyway.java:1413)
    at org.flywaydb.core.Flyway.migrate(Flyway.java:930)
    at org.springframework.boot.autoconfigure.flyway.FlywayMigrationInitializer.afterPropertiesSet(FlywayMigrationInitializer.java:66)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1687)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1624)
    ... 11 more

I have read some many possible solutions on here but still no joy and even read the official boxfuse website to make sense of what to do but still being able to find a solution. My files are in src/main/resources/db.migration and named as V1__Create_Books_Table.sql and V2__Add_Books.sql. I also see the log message: [main] DEBUG org.flywaydb.core.internal.command.DbSchemas - Schema "PUBLIC" already exists. Skipping schema creation. Any help to solve this will be much appreciated. Thanks guys!

回答1:

I've solved this problem by adding the Spring boot flyway definitions within the application.properties for flyway.baseline-version instead of using the boxfuse gradle plugin.