implementation("io.micronaut.liquibase:micronaut-liquibase")
Micronaut Liquibase
Integration between Micronaut and Liquibase
Version:
1 Introduction
To use the Micronaut’s integration with Liquibase you must have the micronaut-liquibase
dependency on your classpath:
<dependency>
<groupId>io.micronaut.liquibase</groupId>
<artifactId>micronaut-liquibase</artifactId>
</dependency>
2 What's New
This section will outline any breaking changes between major or milestone releases as well as detail any new features that have been added.
2.0.0.M1
-
Upgrade to Micronaut 2.0.0.M3.
-
Rename package
io.micronaut.configuration.dbmigration.liquibase
toio.micronaut.liquibase
.
1.3.0
-
Fix issue with Micronaut Data #441.
-
Upgrade to Micronaut 1.3.3.
1.2.0
-
Support for GORM data sources has been added. See the documentation for more information.
1.1.0
-
Upgrade to Micronaut 1.1.4.
-
Stop the application when there is an error applying a migration.
1.0.0
-
Underlying implementation has been changed to run the migrations as soon as possible. If you are not extending or overriding the API, there are no functional changes to note.
1.0.0.RC1
-
First public release.
3 Configuration
You can define liquibase configuration for each datasource. The following example demonstrates using it:
datasources:
default: (3)
url: 'jdbc:h2:mem:liquibaseDisabledDb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE'
username: 'sa'
password: ''
driverClassName: 'org.h2.Driver'
jpa:
default: (3)
packages-to-scan:
- 'example.micronaut'
properties:
hibernate:
hbm2ddl:
auto: none (1)
show_sql: true
liquibase:
datasources: (2)
default: (3)
change-log: 'classpath:db/liquibase-changelog.xml' (4)
1 | Disable schema DDL creation. |
2 | Define all liquibase configuration under key liquibase.datasources . |
3 | Configure liquibase configuration for default data source. |
4 | Root changelog under src/main/resources/db/liquibase-changelog.xml . |
Often, you will have a root changelog:
<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd">
<include file="changelog/01-create-books-schema.xml" relativeToChangelogFile="true"/>
<include file="changelog/02-insert-data-books.xml" relativeToChangelogFile="true"/>
</databaseChangeLog>
which imports changelogs which you keep generating as your app evolves:
<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd">
<changeSet id="01" author="sdelamo">
<createTable tableName="books"
remarks="A table to contain all books">
<column name="id" type="int">
<constraints nullable="false" unique="true" primaryKey="true"/>
</column>
<column name="name" type="varchar(255)">
<constraints nullable="false" unique="true"/>
</column>
</createTable>
</changeSet>
</databaseChangeLog>
Liquibase migrations are executed when datasources are created. Because Micronaut beans are, by default, created
lazily, if you do not inject a Datasource somewhere, then migrations are not executed.
This may be the case when you create a command in a separate module just to run migrations, e.g. using Micronaut support
for picocli.
In this case it is enough to inject a Datasource in anyone of your singletons and migrations will be executed.
|
There are several options available for configuration:
Property | Type | Description |
---|---|---|
|
boolean |
Whether liquibase operations should be run asynchronously. |
|
boolean |
Sets whether this liquibase configuration is enabled. Default value (true). |
|
java.lang.String |
Change log configuration path. |
|
java.lang.String |
Default database schema. |
|
java.lang.String |
Schema to use for Liquibase objects. |
|
boolean |
Whether to first drop the database schema. Default value (false). |
|
java.lang.String |
Tablespace to use for Liquibase objects. |
|
java.lang.String |
Name of table to use for tracking change history. |
|
java.lang.String |
Name of table to use for tracking concurrent Liquibase usage. |
|
java.lang.String |
a tag. |
|
java.lang.String |
Comma-separated list of runtime contexts to use. |
|
java.lang.String |
Comma-separated list of runtime labels to use. |
|
boolean |
Whether rollback should be tested before update is performed. Default value (false). |
|
boolean |
Ignores classpath prefix during changeset comparison. Default value (true). |
|
java.lang.String |
Path to file to which rollback SQL is written when an update is performed. |
|
java.util.Map |
Change log parameters. |
4 GORM Support
There is also support for running Liquibase migrations when using GORM.
1.- Add the dependency:
implementation("io.micronaut.configuration:micronaut-hibernate-gorm")
<dependency>
<groupId>io.micronaut.configuration</groupId>
<artifactId>micronaut-hibernate-gorm</artifactId>
</dependency>
2.- You also need at least one class annotated with @grails.gorm.annotation.Entity
to trigger the migrations.
package example
import grails.gorm.annotation.Entity
import io.micronaut.context.annotation.Requires
@Entity
class Book {
String name
}
3.- Then it is necessary to configure GORM datasource:
dataSource: (1)
pooled: true
jmxExport: true
dbCreate: none (2)
url: 'jdbc:h2:mem:GORMDb'
driverClassName: org.h2.Driver
username: sa
password: ''
liquibase:
datasources: (3)
default: (4)
change-log: classpath:db/liquibase-changelog.xml (5)
1 | Definition of the first data source in GORM. The name it’s default and it can’t be changed. |
2 | Disable schema DDL creation. |
3 | Define liquibase configuration under liquibase.datasources key. |
4 | Define liquibase configuration for the default datasource. |
5 | The migration file path is src/main/resources/db/liquibase-changelog.xml . |
Multiple Data sources
It is also possible to configure Liquibase migrations with multiple data sources when using GORM:
dataSource: (1)
pooled: true
jmxExport: true
dbCreate: none
url: 'jdbc:h2:mem:liquibaseGORMDb'
driverClassName: org.h2.Driver
username: sa
password: ''
dataSources:
books: (2)
pooled: true
jmxExport: true
dbCreate: none
url: 'jdbc:h2:mem:liquibaseBooksDb'
driverClassName: org.h2.Driver
username: sa
password: ''
liquibase:
datasources:
default: (3)
change-log: classpath:db/liquibase-changelog.xml
books: (4)
change-log: classpath:db/liquibase-changelog.xml
1 | Definition of the first data source in GORM. The name it’s default and it can’t be changed. |
2 | Name of the additional data source. |
3 | Define liquibase configuration for the default datasource. |
4 | Define liquibase configuration for the books datasource. |
For more information about how to configure GORM, take a look at the documentation. |
5 Endpoint
This configuration provides a built-in endpoint to expose all the applied migrations in /liquibase
.
To enable the endpoint add the following to the configuration:
endpoints:
liquibase:
enabled: true (1)
sensitive: false (2)
1 | /liquibase endpoint is enabled. |
2 | /liquibase endpoint is open for unauthenticated access. |
$ curl http://localhost:8080/liquibase
[{
"name": "default",
"changeSets": [{
"author": "sdelamo",
"changeLog": "classpath:db/changelog/01-create-books-and-author-schema.xml",
"comments": "",
"contexts": [],
"dateExecuted": "2018-10-29T16:33:05Z",
"deploymentId": "0830784929",
"description": "createTable tableName=books; createTable tableName=authors; addForeignKeyConstraint baseTableName=books, constraintName=author_fk, referencedTableName=authors",
"execType": "EXECUTED",
"id": "01",
"labels": [],
"checksum": "8:140eb966bb6a14bccade2c2d9133b7d3",
"orderExecuted": 1,
"tag": "tag1"
}, {
"author": "sdelamo",
"changeLog": "classpath:db/changelog/02-insert-data-authors.xml",
"comments": "Inserting Authors",
"contexts": [],
"dateExecuted": "2018-10-29T16:33:05Z",
"deploymentId": "0830784929",
"description": "insert tableName=authors; insert tableName=authors; insert tableName=authors; insert tableName=authors; insert tableName=authors",
"execType": "EXECUTED",
"id": "02",
"labels": [],
"checksum": "8:6204c525ce5c1c55f064888d078b8f05",
"orderExecuted": 2,
"tag": null
}]
}]
See the section on Built-in endpoints in the user guide for more information. |