I'm having a hard time setting up LiquiBase in my Spring Boot project. I tried looking through the docs and finding some guides - but they seem contradict each other :(
I wish to use LiquiBase via Gradle and I want it to generate the changelogs from Hibernate and end up with a SQL script I can run on the server to update the schema to the appropriate version.
To get it to run via Gradle I'm using this plugin https://github.com/liquibase/liquibase-gradle-plugin using the recommended setup shown in their README.
To get the Hibernate diff to work I'm using https://github.com/liquibase/liquibase-hibernate
Here's my build.gradle file:
buildscript {
ext {
springBootVersion = '2.0.5.RELEASE'
}
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
plugins {
id 'java'
id 'net.ltgt.apt' version '0.10' // https://projectlombok.org/setup/gradle
id 'org.liquibase.gradle' version '2.0.1' // https://github.com/liquibase/liquibase-gradle-plugin
}
apply plugin: 'eclipse-wtp'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
apply plugin: 'war'
group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = 1.8
repositories {
mavenCentral()
maven {
credentials {
username = oracleUser
password = oraclePass
}
url 'https://www.oracle.com/content/secure/maven/content'
}
}
liquibase {
activities {
main {
changeLogFile 'main.groovy'
url 'jdbc:oracle:thin:@localhost:1521:XE'
referenceUrl 'hibernate:spring:com.example?dialect=org.hibernate.dialect.Oracle10gDialect'
username 'user'
password 'pass'
}
}
}
configurations {
providedRuntime
}
dependencies {
compile('org.springframework.boot:spring-boot-starter-data-jpa')
compile('org.springframework.boot:spring-boot-starter-data-rest')
compile('org.springframework.boot:spring-boot-starter-hateoas')
compile('org.springframework.boot:spring-boot-starter-jooq')
compile('org.springframework.boot:spring-boot-starter-web')
compile('org.springframework.boot:spring-boot-starter-mail')
compile('com.github.waffle:waffle-spring-boot-starter:1.9.0')
compile('com.oracle.jdbc:ojdbc8:12.2.0.1')
runtime('org.springframework.boot:spring-boot-devtools')
compileOnly('org.projectlombok:lombok')
apt('org.projectlombok:lombok:1.18.2')
liquibaseRuntime('org.liquibase:liquibase-core:3.6.2')
liquibaseRuntime('org.liquibase:liquibase-groovy-dsl:2.0.1')
liquibaseRuntime('org.liquibase.ext:liquibase-hibernate5:3.6')
liquibaseRuntime('com.oracle.jdbc:ojdbc8:12.2.0.1') // duplicate...
providedRuntime('org.springframework.boot:spring-boot-starter-tomcat')
testCompile('org.springframework.boot:spring-boot-starter-test')
testCompile('org.springframework.restdocs:spring-restdocs-mockmvc')
}
Running it via
> .\gradlew diffChangeLog -PrunList=main
But fails with
Task :diffChangeLog liquibase-plugin: Running the 'main' activity... Starting Liquibase at Wed, 26 Sep 2018 13:36:24 CEST (version 3.6.2 built at 2018-07-03 11:28:09) Exception in thread "main" java.lang.NoClassDefFoundError: org/springframework/core/io/ClassPathResource at liquibase.ext.hibernate.database.HibernateSpringPackageDatabase.isXmlFile(HibernateSpringPackageDatabase.java:54)
It looks like it cannot find Spring Boot. So I then tried removing the liquibaseRuntime
but then the LiquiBase Gradle plugin complains that liquibaseRuntime
is missing.
Seems I'm stuck in a loop. What is a sane way of setting this up?
I really don't want to repeat every dependency inside the liquibaseRuntime
. Also the doc literally says:
dependencies { // All of your normal project dependencies would be here in addition to... liquibaseRuntime 'org.liquibase:liquibase-core:3.6.1' liquibaseRuntime 'org.liquibase:liquibase-groovy-dsl:2.0.1' liquibaseRuntime 'mysql:mysql-connector-java:5.1.34' }
Note the
// All of your normal project dependencies would be here in addition to...
So yeah. Why...
Please help!
Also... I noticed that you have to write database config twice. Why is that needed when it's already set in spring boot config?
PROGRESS
So changing liquibaseRuntime
to
liquibaseRuntime('org.liquibase:liquibase-core:3.6.2')
liquibaseRuntime('org.liquibase:liquibase-groovy-dsl:2.0.1')
liquibaseRuntime('org.liquibase.ext:liquibase-hibernate5:3.6')
liquibaseRuntime('com.oracle.jdbc:ojdbc8:12.2.0.1')
liquibaseRuntime('org.springframework.boot:spring-boot-starter-data-jpa')
liquibaseRuntime files('src/main')
Makes the errors go away. But it still doesn't work.
Running this command
.\gradlew diff
Gives me this output
> Task :diff liquibase-plugin: Running the 'main' activity... Starting Liquibase at Wed, 26 Sep 2018 16:47:19 CEST (version 3.6.2 built at 2018-07-03 11:28:09) Diff Results: Reference Database: null @ hibernate:spring:com.example.model?dialect=org.hibernate.dialect.Oracle10gDialect (Default Schema: HIBERNATE) Comparison Database: SYSTEM @ jdbc:oracle:thin:@localhost:1521:XE (Default Schema: SYSTEM) Compared Schemas: HIBERNATE -> SYSTEM Product Name: Reference: 'Hibernate' Target: 'Oracle' Product Version: Reference: '5.2.17.Final' Target: 'Oracle Database 11g Express Edition Release 11.2.0.2.0 - 64bit Production' Missing Catalog(s): HIBERNATE Unexpected Catalog(s): NONE Changed Catalog(s): NONE Missing Column(s): NONE Unexpected Column(s): NONE Changed Column(s): NONE Missing Foreign Key(s): NONE Unexpected Foreign Key(s): NONE Changed Foreign Key(s): NONE Missing Index(s): NONE Unexpected Index(s): NONE Changed Index(s): NONE Missing Primary Key(s): NONE Unexpected Primary Key(s): NONE Changed Primary Key(s): NONE Missing Sequence(s): NONE Unexpected Sequence(s): NONE Changed Sequence(s): NONE Missing Stored Procedure(s): NONE Unexpected Stored Procedure(s): NONE Changed Stored Procedure(s): NONE Missing Table(s): NONE Unexpected Table(s): NONE Changed Table(s): NONE Missing Unique Constraint(s): NONE Unexpected Unique Constraint(s): NONE Changed Unique Constraint(s): NONE Missing View(s): NONE Unexpected View(s): NONE Changed View(s): NONE Liquibase command 'diff' was executed successfully. BUILD SUCCESSFUL in 7s 1 actionable task: 1 executed
When running against an empty database. So yeah - it doesn't work :(
Hibernate can be used with several databases that are supported by Liquibase, such as H2. To use an H2 database with Liquibase, you must have the H2 JDBC driver JAR file., which is pre-installed with Liquibase.
Integrating Liquibase into your Spring Boot application is extremely easy. You just have to add the Liquibase Core to your classpath. That's all you need to do. The Liquibase integration will automatically load the master changelog file from the db changelog directory.
I know this is an old thread, but I wanted to add some clarification for those who find this answer later...
The liquibaseRuntime
configuration does not inherit from any other configuration. This is because in most cases, Liquibase only needs to be able to parse the change logs and connect to the database. To use something like the Hibernate module, or to generate change logs from your code, you need to add extra things to the liquibaseRuntime, such as Hibernate or Spring Data, and you'd need srcSets.main.output
to be able to find your project files themselves.
The comment that said "All of your normal project dependencies would be here in addition to..." referred to the fact that you would have a bunch of other dependencies in the block to build and run your project, not that they would be part of the liquibaseRuntime
configuration. If you do want all of the libraries from your project to also be part of the liquibaseRuntime
, you can add configurations.liquibaseRuntime.extendsFrom configurations.runtime
you your build.gradle, or if you already have a configurations
block, you can add liquibaseRuntime.extendsFrom runtime
to that block. This should add all the project dependencies, and the project files themselves, to your liquibaseRuntime.
I hope this helps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With