Search code examples
sql-serverhibernategrailsjdbch2

After specifying an alternate datasource, grails is throwing a sql exception for embedded h2


I have a small set of grails 3.0.11 applications. We have a domain module which is shared between the applications. When one of the apps(app1, app2, etc) starts up, it connects to the datasource and creates a table for every class in the domain module. All of the apps in the suite will attempt to create these tables.

I modified the application.yml so that it would use an MSSQL instance rather than the internal h2 db, and I set dbCreate to update so that the schema will persist through shutdowns of the application.

I am trying to split up the domain so that each application will only manage the schema for its relevant classes. ie, app1 will handle ddl for classA, classB, and classC on startup, and app2 will handle classX, classY, classZ. Following this guide, I have defined a second datasource unique to each app (i.e., app1db, app2db, etc), and I have added mapping = { datasource 'appXdb'} to each class specifying the relevant app.

Now, when I start the app, I am getting a sql exception:

Caused by: java.sql.SQLException: Driver:jTDS 1.3.1 returned null for URL:jdbc:h2:mem:grailsDB;MVCC=TRUE;LOCK_TIMEOUT=10000

Why is my app still trying to access an h2 db after redefining datasource to point to an mssql instance and adding a second datasource which also points to mssql?

application.yml:

---
server:
  port: 3434
  contextPath: '/app1'
---
grails:
    profile: web
    codegen:
        defaultPackage: cars.app
info:
    app:
        name: '@info.app.name@'
        version: '@info.app.version@'
        grailsVersion: '@info.app.grailsVersion@'
spring:
    groovy:
        template:
            check-template-location: false

---
grails:
    mime:
        disable:
            accept:
                header:
                    userAgents:
                        - Gecko
                        - WebKit
                        - Presto
                        - Trident
        types:
            all: '*/*'
            atom: application/atom+xml
            css: text/css
            csv: text/csv
            form: application/x-www-form-urlencoded
            html:
              - text/html
              - application/xhtml+xml
            js: text/javascript
            json:
              - application/json
              - text/json
            multipartForm: multipart/form-data
            pdf: application/pdf
            rss: application/rss+xml
            text: text/plain
            hal:
              - application/hal+json
              - application/hal+xml
            xml:
              - text/xml
              - application/xml
    urlmapping:
        cache:
            maxsize: 1000
    controllers:
        defaultScope: singleton
    converters:
        encoding: UTF-8
    views:
        default:
            codec: html
        gsp:
            encoding: UTF-8
            htmlcodec: xml
            codecs:
                expression: html
                scriptlets: html
                taglib: none
                staticparts: none
---
hibernate:
    cache:
        queries: false
        use_second_level_cache: true
        use_query_cache: false
        region.factory_class: 'org.hibernate.cache.ehcache.EhCacheRegionFactory'

endpoints:
    jmx:
        unique-names: true
    shutdown:
        enabled: true
dataSources:
    dataSource:
        pooled: true
        jmxExport: true
        driverClassName: net.sourceforge.jtds.jdbc.Driver
        username: grails
        password: password
    app1DataSource:
        pooled: true
        jmxExport: true
        driverClassName: net.sourceforge.jtds.jdbc.Driver
        username: grails
        password: password

environments:
    development:
        dataSource:
            dbCreate: update
            url: jdbc:jtds:sqlserver://127.0.0.1;databaseName=cars_demo
        appDataSource:
            dbCreate: update
            url: jdbc:jtds:sqlserver://1127.0.0.1;databaseName=cars_demo

        dataSource:
            dbCreate: update
            url: jdbc:h2:mem:testDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE;DB_CLOSE_DELAY=-1
    production:
        dataSource:
            dbCreate: update
            url: jdbc:h2:mem:prodDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE;DB_CLOSE_DELAY=-1
            properties:
                jmxEnabled: true
                initialSize: 5
                maxActive: 50
                minIdle: 5
                maxIdle: 25
                maxWait: 10000
                maxAge: 600000
                timeBetweenEvictionRunsMillis: 5000
                minEvictableIdleTimeMillis: 60000
                validationQuery: SELECT 1
                validationQueryTimeout: 3
                validationInterval: 15000
                testOnBorrow: true
                testWhileIdle: true
                testOnReturn: false
                jdbcInterceptors: ConnectionState
                defaultTransactionIsolation: 2 # TRANSACTION_READ_COMMITTED

mapping element: static mapping = {datasource 'app1DataSource'}

edit1: added application.yml and mapping element.


Solution

  • turns out, I had not properly nested my environmental overwrites in application.yml. I added a parent element dataSources: about the actual ds defs in the main section but did not do the same in the environment sections which mean that my ds's were loading w/o a url which then defaulted to grails h2 db.

    Thanks @quindimildev! I recognized my oversight while trying to figure out formatting to follow your suggestion.