Sadly, and annoyingly, groovy.util.slurpersupport.NodeChild doesn’t have a nice toString() implementation when dealing with results obtained from groovy.util.XmlSlurper. For convenience, you can add the following meta-method to NodeChild to serialize xml nodes:

NodeChild.metaClass.toXmlString = {
	def self = delegate
	new StreamingMarkupBuilder().bind { 
		delegate.mkp.xmlDeclaration() // Use this if you want an XML declaration
		delegate.out << self

In grails, you would typically run such code from a thread-safe location such as from within a plugin or inside BootStrap.groovy. Then, in your application you can use:

def xml = new XmlSlurper().parseText('<a>b</a>')
println xml.toXmlString()

This is handy when building REST APIs that require both text and node based version of xml, such as an API proxy.

When wrestling with GORM queries you may find yourself needing to turn on SQL logging in grails. This is quite easy to setup in DataSource.groovy by setting logSql:

dataSource {
	// ...
	logSql = true

However, I find it more convenient and safer to switch this value from the command line:

grails -DlogSql=true run-app

This is possible if you change your DataSource.groovy slightly:

dataSource {
	// ...
	logSql = Boolean.parseBoolean( ?: 'false')

The fun doesn’t stop there. We can do a bit better (although much more verbose) by also logging result sets and parameter bindings. To set this up, we need to modify Config.groovy:

log4j = {
	appenders {
		// ...
	root {
		// ...
	// Your application specific logging configuration here ...
	if (Boolean.parseBoolean( ?: 'false')) {
		trace	'org.hibernate.SQL',

Now, with the flip of some swiches, our command line interface to run-app now looks like this:

grails -DlogSql=true -DtraceSql=true run-app

This will give us the essential information we need to tackle some really hardcode SQL issues. The fact that it is set on the command line ensures that we don’t accidentally check-in these values for our production settings. This is a good thing since it creates a great deal of information that can quickly fill up a hard drive.

If you want terser output, at the expensive of being more invasive, you should consider the p6spy plugin.

When setting up a domain model in GORM, it is often handy to create a abstract base class to inherit common table attributes. For those familiar with JPA, @MappedSuperclass provides this capability. With grails, this can be achieved simply by inheriting from an abstract base domain class such as the following:

abstract class Base {
   Date dateCreated
   Date lastUpdated
   String updatedApplication = 'app'
   String updatedBy
   String codeVersion = '$Revision: 1.2 $'

   static constraints = {
      updatedApplication(maxSize:64, nullable:true)
      updatedBy(maxSize:32, nullable:true)
      codeVersion(maxSize:64, nullable:true)

   static mapping = {
      columns {

   static addColumnMappings = { Object d ->
      delegate = d
      dateCreated column: 'CRT_DTTM'
      lastUpdated column: 'LST_UPD_DTTM'
      updatedApplication column: 'LST_UPD_APP'
      updatedBy column: 'LST_UPD_USR'
      codeVersion column: 'CD_VRSN'

The class above shows how it is possible to override the default conventions in grails with its ORM Mapping DSL. However, grails currently does not support the merging of parent and subclass column mappings as it does with constraints. This leads to having to redefine parent column mappings in each of the subclasses. In an effort to be more DRY, there is a better way. By creating a static closure called addColumnMappings, subclasses can then invoke this method inside of their static mapping / columns closure:

class Country extends Base {
	String name
	String isoCode
	Integer sortOrder

	static constraints = {
		name(maxSize:32, nullable:true)
		isoCode(maxSize:2, nullable:true)
	static mapping = {
		table 'COUNTRY'
		version column: 'RW_VRSN'
		sort 'sortOrder'
		columns {
			id column: 'C_ID'
			name column: 'NM'
			isoCode column: 'ISO_CD'
			sortOrder column: 'SRT_ORDR'

Note the passing of the closure’s delegate. This allows the addColumnMappings closure to adjust its delegate internally and the code to execute as if it were inlined in calling class.

In conclusion, this method allows one to centralize common column mappings to a common domain base class. Although it requires manual intervention to invoke a helper method, it’s much better than the alternative approach of repeating yourself.


Get every new post delivered to your Inbox.