I'm trying to implement liquibase in an existing SpringBoot project with MYSQL database. I want to be able to generate changesets which specify the differences when an entity is changed.
What I've done:
I've added liquibase dependencies and the gradle liquibase plugin in my build.gradle
file. After making a domain change, I've run gradle generateChangeLog
. The command executes successfully but nothing happens.
I read somewhere that this gradle plugin works only for the inmemory h2 database? Is that true? If yes then what alternative should I use to generate changelogs automatically.
I could not find a working SpringBoot gradle based example which uses MYSQL and has liquibase implemented WITH automatic change generation ability. It would be great if someone could provide that.
References:
https://github.com/stevesaliman/liquibase-workshop
https://github.com/liquibase/liquibase-gradle-plugin
The solutions is to write a gradle task which invokes liquibase diffChangeLog
Create a liquibase.gradle
file in the project root directory, add liquibase-hibernate extension and write a gradle task that invokes the liquibase diffChangeLog
command.
configurations {
liquibase
}
dependencies {
liquibase group: 'org.liquibase.ext', name: 'liquibase-hibernate4', version: 3.5
}
//loading properties file.
Properties liquibaseProps = new Properties()
liquibaseProps.load(new FileInputStream("src/main/resources/liquibase-task.properties"))
Properties applicationProps = new Properties()
applicationProps.load(new FileInputStream("src/main/resources/application.properties"))
task liquibaseDiffChangelog(type: JavaExec) {
group = "liquibase"
classpath sourceSets.main.runtimeClasspath
classpath configurations.liquibase
main = "liquibase.integration.commandline.Main"
args "--changeLogFile=" + liquibaseProps.getProperty('liquibase.changelog.path')+ buildTimestamp() +"_changelog.xml"
args "--referenceUrl=hibernate:spring:" + liquibaseProps.getProperty('liquibase.domain.package') + "?dialect=" + applicationProps.getProperty('spring.jpa.properties.hibernate.dialect')
args "--username=" + applicationProps.getProperty('spring.datasource.username')
args "--password=" + applicationProps.getProperty('spring.datasource.password')
args "--url=" + applicationProps.getProperty('spring.datasource.url')
args "--driver=com.mysql.jdbc.Driver"
args "diffChangeLog"
}
def buildTimestamp() {
def date = new Date()
def formattedDate = date.format('yyyyMMddHHmmss')
return formattedDate
}
NOTE: I have used properties files to pass arguments to the liquibase command, you could add the values directly, but that would not be a good practice.
Next, you would need to apply the liquibase.gradle
file from within the project's build.gradle
file. and add the liquibase dependency
apply from: 'liquibase.gradle'
//code omitted
dependencies {
compile (group: 'org.liquibase', name: 'liquibase-core', version: "3.4.2")
}
After this step liquibase would be setup completely.
You can now use
gradle liquibaseDiffChangeLog
to generate changelogs.
With the following setup it can be used in conjunction with the liquibase-hibernate
and liquibase-gradle
extensions:
plugins {
id 'org.liquibase.gradle' version '2.0.1'
}
dependencies {
implementation 'org.liquibase:liquibase-core:3.8.0'
liquibaseRuntime 'org.liquibase.ext:liquibase-hibernate5:3.8'
liquibaseRuntime sourceSets.main.runtimeClasspath
liquibaseRuntime sourceSets.main.output
}
def props = new Properties()
file("src/main/resources/liquibase.properties").withInputStream { props.load(it) }
diff.dependsOn assemble
diffChangeLog.dependsOn assemble
liquibase {
activities {
main {
changeLogFile props.getProperty("liquibase.changelog.main")
referenceUrl props.getProperty("liquibase.changelog.referenceUrl")
url props.getProperty("spring.datasource.url")
username props.getProperty("spring.datasource.username")
password props.getProperty("spring.datasource.password")
referenceDriver "liquibase.ext.hibernate.database.connection.HibernateDriver"
}
}
}
This will generate a changelog in the specified changelog file. You can first generate an initial changelog with gradle generateChangelog
, run your application to apply these changes to the database and then after each change in your entity models run the gradle diffChangelog
task to get these changes in the chanlog file. These should then be applied to the database before running the diffChangeLog
task again to prevent duplicate operations in the changelog.
For this to work you will need the following properties in liquibase.properties
:
liquibase.changelog.main=src/main/resources/db/changelog/db.changelog-master.xml
liquibase.changelog.classpath=classpath:db/changelog/db.changelog-master.xml
liquibase.changelog.referenceUrl=hibernate:spring:<MODEL_PACKAGE>?dialect=org.hibernate.dialect.MySQL5Dialect
IMPORTANT: Be sure to replace <MODEL_PACKAGE>
with the package where your hibernate models are located.
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