Alan Hensel
Alan Hensel

Reputation: 833

Validate GORM model after migrations

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

Answers (1)

Burt Beckwith
Burt Beckwith

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

Related Questions