Reputation: 833
We're getting started with running Liquibase migrations on Grails server startup. We'd like to use dbCreate='validate' on the dataSource, to ensure that the database and object model stay in sync. Our datasource config currently looks like this:
development {
dataSource_dbm {
dbCreate = ''
url = "jdbc:h2:mem:devDb;MVCC=TRUE;LOCK_TIMEOUT=10000;MODE=Oracle"
username = 'sa'
password = ''
}
dataSource {
dbCreate = 'validate'
url = "jdbc:h2:mem:devDb;MVCC=TRUE;LOCK_TIMEOUT=10000;MODE=Oracle"
username = 'sa'
password = ''
}
}
with
grails.plugin.databasemigration.dbm.updateOnStart = true
grails.plugin.databasemigration.dbm.updateOnStartFileNames = ['changelog.groovy']
in our Config.groovy. This results in some errors on startup:
Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'transactionManager':
Cannot resolve reference to bean 'sessionFactory' while setting bean property 'sessionFactory';
nested exception is org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'sessionFactory':
Invocation of init method failed;
nested exception is org.hibernate.HibernateException:
Missing table: ...
It looks as though the default dataSource is created and the dbCreate policy applied before the liquibase migrations are run.
If we comment out the second dataSource, we see that all of the migrations are indeed applied at startup.
Is there a way to configure our datasources or the databasemigration plugin such that the migrations are run before validation? Or do we have to give up on validation on server startup, and use a dataSource with dbCreate='', and depend on runtime errors to catch problems?
Upvotes: 3
Views: 1045
Reputation: 75671
You can validate the schema yourself, in the same way that the schema-export
script lets you capture the SQL that Hibernate runs if you're using "create-drop". If you have access to the Spring ApplicationContext
(here I'm getting it by dependency-injecting the grailsApplication
bean) then you can run this in BootStrap:
import org.hibernate.tool.hbm2ddl.SchemaValidator
def grailsApplication
....
def ctx = grailsApplication.mainContext
def sessionFactoryFactory = ctx.getBean('&sessionFactory')
def sessionFactory = ctx.getBean('sessionFactory')
def configuration = sessionFactoryFactory.configuration
def settings = sessionFactory.settings
def validator = new SchemaValidator(configuration, settings)
validator.validate()
This might make a good addition to the plugin, if you create an enhancement request at http://jira.grails.org/browse/GPDATABASEMIGRATION I'll look at adding it in an upcoming release.
Upvotes: 1