Search code examples
grailsgrails-orm

In grails 4.0.5, moving datasource definition to runtime.groovy causes DB not to be created during tests


I need to move the configuration of the datasource to runtime.groovy, because that configuration code need to access some of my classes.

In previous versions of grails, this was not an issue. However i find that if I move the environments block, and the default datasource block to runtime.groovy, Hibernate will not create the database, and my functional tests fail, obviously.

This is the configuration that I removed from application.yml:

hibernate:
    cache:
        queries: false
        use_second_level_cache: false
        use_query_cache: false

dataSource:
    pooled: true
    jmxExport: true
    driverClassName: org.h2.Driver
    username: sa
    password: ''

environments:
    development:
        grails.plugin.console.csrfProtection.enabled: false
        dataSource:
            dbCreate: create-drop
            url: jdbc:h2:mem:devDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE
    test:
        dataSource:
            dbCreate: update
            url: jdbc:h2:mem:testDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE
    production:
        hibernate:
            jdbc:
                use_get_generated_keys: true

Which in my runtime.groovy looks like this:

hibernate {
    cache {
        queries = false
        use_second_level_cache = false
        use_query_cache = false
    }
}

dataSource {
    pooled = true
    jmxExport = true
    driverClassName = "org.h2.Driver"
    username = "sa"
    password = ""
}

environments {
    development {
        dataSource {
            dbCreate = "create-drop"
            url = "jdbc:h2:mem:devDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE"
        }
    }
    test {
        dataSource {
            dbCreate: "update"
            url: "jdbc:h2:mem:testDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE"
        }
    }

    production {
        hibernate {
            jdbc {
                use_get_generated_keys = true
            }
        }

        dataSource {
//production datasource setup irrelevant
        }
    }

I tried combinations, keeping some of it in application.yml, some of it in application.groovy, all of it in runtime.groovy. Keeping the test and dev sections in application.yml, and the runtime-specific environments in runtime.groovy, does not work either.

Nothing seems to work.

I can't leave it like this because my production mode needs to be able to connect a secrets store to set up the production datasource.

Is there some hidden switch I am missing with the newer versions of grails?

Additional notes, the following commands do work (server starts up):

./grailsw -Dgrails.env=dev run-app
./grailsw -Dgrails.env=test run-app
./gradlew shell -q

The tests fail complaining about missing tables when i run this:

./grailsw -Dgrails.env=test test-app

The tests that are failing are inheriting from GebSpec, as they are full functional tests that need to run against the controllers.

So it seems like Hibernate is not properly initializing when running functional tests, if I move the configuration away from application.yml?

Thanks

FINAL UPDATE There is a typo in my code, as Jeff pointed it out. Thanks Jeff!


Solution

  • The config you show for your runtime.groovy should be in grails-app/conf/application.groovy (does not need to be runtime.groovy). The problem with your config is you have this:

    test {
        dataSource {
            dbCreate: "update"
            url: "jdbc:h2:mem:testDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE"
        }
    }
    

    You have colons where you should have equals signs, like this:

    test {
        dataSource {
            dbCreate = "update"
            url = "jdbc:h2:mem:testDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE"
        }
    }