I have a relatively new Grails project using 3.0.14. I am looking to integrate liquibase for database migrations via the Database Migration plugin (2.0.0.RC4).
I have a large enough domain model so far that I have used the plugin to 'seed' an initial changelog. This is straight from the docs, and works as intended:
grails dbm-generate-gorm-changelog changelog.groovy
What I am now trying to test/get working is the dbm-gorm-diff
command, which will take changes to the domain model and create a changelog that can be applied. This is where I am running into issues.
The Grails documentation suggest removing the dbCreate
block from the datasource to ensure that Hibernate doesn't do the updating, and Liquibase can take over. Great, exactly what I want.
When I remove dbCreate
, Grails/hibernate still seems to update the database before the Database Migration plugin has a chance to do the diff. When doing the diff, it is already too late to see changes, so the changelogs do not contain the right data.
dataSource:
pooled: true
jmxExport: true
driverClassName: org.h2.Driver
username: sa
password:
environments:
development:
dataSource:
dbCreate: verify
driverClassName: org.postgresql.Driver
dialect: org.hibernate.dialect.PostgreSQLDialect
url: jdbc:postgresql://127.0.0.1:5432/liquibase_test
username: dbuser
password: dbuser
logSql: false
formatSql: true
(I am aware that the dbCreate is set to verify. More on this later)
dbcreate -U dbuser liquibase_test
grails dbm-update
select * from databasechangelog
equals the number of changes in changelog.groovy
Add a new simple domain class:
class TestDomain {
int testInt
}
Run the plugin to get the diff - grails dbm-gorm-diff add-simple-domain.groovy
. The command fails with an exception:
:DataModel:dbmGormDiff
Command execution error: liquibase.command.CommandExecutionException: java.lang.NullPointerException
DataModel:dbmGormDiff FAILED
Now, remove the config dbCreate: verify
from above, and run again
This completes successfully without exception, but there are issues:
add-simple-domain.groovy
, but it has no mention of the new domain class I just created. (It has index/sequences, but I think this is a known issue)databasechangelog
still has the original row count, and even when interrogated no reference to the new domain classSo, I'm at a loss to explain what is going on. I can deal with the extra create/drop indexes & sequences, but I can't seem to get the liquibase stuff working. Can anyone shed some light on this for me?
I did some more digging into the NullPointer, and it seems to come from the class liquibase/ext/hibernate/snapshot/ForeignKeySnapshotGenerator.java:45
, where the plugin is trying to construct a foreign key to the inherited table id field (using tablePerHierarchy false
for this inheritance). I couldn't find anything that seemed related to this error after a decent search.
I have found an issue on Github for the tablePerHierarchy
NPE: https://github.com/grails-plugins/grails-database-migration/issues/68
I ended up getting this to work by setting hibernate.hbm2ddl.auto = 'none'
in my application.groovy
. Interestingly, when I tried to instead put this same config in my application.yml
it had no effect.
I suspect there may be other forces at play here as I tried replicating the behaviour on a fresh Grails project without issue.
For the time being I have settled on using the hibernate property in the groovy file, though I am still curious as to why I couldn't get the config to work for me like a vanilla project.