Tuesday, September 16, 2014

Grails : database management in multiple environments


With Grails, you can use a database for a specific environments.If you change environments, Grails will use the database you define.

For example, you can define the following environments :

  • development: In memory database
  • test:               Mysql on localhost
  • production :   Mysql on production machine

Define your environments in DataSource.groovy



hibernate {
    cache.use_second_level_cache = true
    cache.use_query_cache = false
    cache.region.factory_class = 'net.sf.ehcache.hibernate.EhCacheRegionFactory' // Hibernate 3
//    cache.region.factory_class = 'org.hibernate.cache.ehcache.EhCacheRegionFactory' // Hibernate 4
}

// environment specific settings
environments {
    development {
        dataSource {
            dbCreate = "create-drop" // one of 'create', 'create-drop', 'update', 'validate', ''
            url = "jdbc:h2:mem:devDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE"
        }
        dataSource_lookup {
            pooled = true
            driverClassName = "org.h2.Driver"
            username = "sa"
            password = ""
        }
    }
    test {
        dataSource {
            pooled = true
            driverClassName = "com.mysql.jdbc.Driver"
            dialect = "org.hibernate.dialect.MySQL5InnoDBDialect"
            dbCreate = "create-drop"
            url = "jdbc:mysql://localhost/toolprod"
            username = "root"
            password = ""
        }

    }
    production {
        grails.config.locations = ["file:/opt/apache-tomcat-7.0.47/conf/ConfigToolprod.groovy"]
    }
}  


Production Environment


As you can see, the way you define production environment is quite different.You define a path where are stored datasource.
With this sort of configuration, you doesn't have to build your Grails project an other time if you want to change the login and password.Moreover, authentication is only in one place.I find it much better.

Below, there is an example of my ConfigToolprod.groovy file. An important thing, this configuration will permit Mysql database to reconnect automaticaly.

Comment : File contains a lot parameter because they had a bug in a old version of Grails.You certainly doesn't need all parameters.



ConfigToolprod.groovy


dataSource {
    pooled = true
    dbCreate = "update"
    url = "jdbc:mysql://localhost/toolprod"
    driverClassName = "com.mysql.jdbc.Driver"
    dialect = org.hibernate.dialect.MySQL5InnoDBDialect
    username = "LOGIN"
    password = "PASSWORD"
    properties {
       // Documentation for Tomcat JDBC Pool
       // http://tomcat.apache.org/tomcat-7.0-doc/jdbc-pool.html#Common_Attributes
       // https://tomcat.apache.org/tomcat-7.0-doc/api/org/apache/tomcat/jdbc/pool/PoolConfiguration.html
       jmxEnabled = true
       initialSize = 5
       maxActive = 50
       minIdle = 5
       maxIdle = 25
       maxWait = 10000
       maxAge = 10 * 60000
       timeBetweenEvictionRunsMillis = 5000
       minEvictableIdleTimeMillis = 60000
       validationQuery = "SELECT 1"
       validationQueryTimeout = 3
       validationInterval = 15000
       testOnBorrow = true
       testWhileIdle = true
       testOnReturn = false
       ignoreExceptionOnPreLoad = true
       // http://tomcat.apache.org/tomcat-7.0-doc/jdbc-pool.html#JDBC_interceptors
       jdbcInterceptors = "ConnectionState;StatementCache(max=200)"
       defaultTransactionIsolation = java.sql.Connection.TRANSACTION_READ_COMMITTED // safe default
       // controls for leaked connections
       abandonWhenPercentageFull = 100 // settings are active only when pool is full
       removeAbandonedTimeout = 120
       removeAbandoned = true
       // use JMX console to change this setting at runtime
       logAbandoned = false // causes stacktrace recording overhead, use only for debugging
       // JDBC driver properties
       // Mysql as example
       dbProperties {
           // Mysql specific driver properties
           // http://dev.mysql.com/doc/connector-j/en/connector-j-reference-configuration-properties.html
           // let Tomcat JDBC Pool handle reconnecting
           autoReconnect=false
           // truncation behaviour
           jdbcCompliantTruncation=false
           // mysql 0-date conversion
           zeroDateTimeBehavior='convertToNull'
           // Tomcat JDBC Pool's StatementCache is used instead, so disable mysql driver's cache
           cachePrepStmts=false
           cacheCallableStmts=false
           // Tomcat JDBC Pool's StatementFinalizer keeps track
           dontTrackOpenResources=true
           // performance optimization: reduce number of SQLExceptions thrown in mysql driver code
           holdResultsOpenOverStatementClose=true
           // enable MySQL query cache - using server prep stmts will disable query caching
           useServerPrepStmts=false
           useServerPrepStmts=false
           // metadata caching
           cacheServerConfiguration=true
           cacheResultSetMetadata=true
           metadataCacheSize=100
           // timeouts for TCP/IP
           connectTimeout=15000
           socketTimeout=120000
           // timer tuning (disable)
           maintainTimeStats=false
           enableQueryTimeouts=false
           // misc tuning
           noDatetimeStringSync=true
       }
    }
}