SpringOne 2GX 2011

Chicago, October 25-28, 2011

Grails: Bootstrapping data with DomainBuilder

Posted by: Andres Almiray on 2012-01-23 06:35:00.0

A few days ago I was discussing the topic of builders during a Grails training session. After surveying the usual suspects found in the standard Groovy distribution (MarkupBuilder, SwingBuilder, Antbuilder and ObjectGraphBuilder) we jumped into Grails' DomainBuilder. Once we got familiar with it the team seized the opportunity to refactor an existing application they've been working on for a few weeks. The idea was to remove a very verbose data setup during the bootstrap sequence.

Like many other applications out there, this one requires setting up users and roles to secure access to some areas. The User and Role classes looked like the following ones

Nothing complex really. Now, during bootstrap there were a handful on instances of both classes being created and saved. A few users would share roles which meant keeping a reference to the common role to later use Grails relationship methods. This caused the code to be not so much DRY, and while it's good to be WET from time to time this wasn't the case. Let me show you how the code looked like before we added the builder

We could have saved a few lines by collecting all domain classes in Lists then applying *.save() on the lists, however that would still have left the relationship methods being defined explicitly. This is where DomainBuilder came in. With it we were able to define the domain instances and the relationships at the same time. We ended up with code looking like the following one

DomainBuilder understands perfectly well the relationships between domain class instances. It also makes some assumptions on how the model is setup, but we still need to give it a few hints. In line 7 we can see a classNameResolver set on the builder. By convention the builder will use an strategy to construct fully qualified classnames out of node names. If the classes happen to be defined inside a package then you must define a custom classNameResolver. In our case the classes we're interested in live under the same package so we only need to specify it, the builder will do the rest to figure out the correct class name.

Next, we must set a custom identifierResolver because the id property is of semantic meaning to domain classes. The builder can keep references to all instantiated nodes, it will use the id property by default, assuming that's a synthetic property. This means it will treated in a different way than the rest of properties. Because id is used by domain classes we set a different synthetic property named nodeId. Finally we define a custom factory to serve as the root of the object graph. This custom factory requires additional setup to handle its children, which is why we also register a custom ChildPropertySetter on the builder. These two helper classes can be seen in the following snippets

Basically the code inspects the type of the parent node. If it's a List then we append the child to it, otherwise we let the standard behavior take control. You can read more information on the builders used at FactoryBuilderSupport and ObjectGraphBuilder.


Keep on Groovying!

About Andres Almiray

Andres Almiray

Andres is a Java/Groovy developer and Java Champion, with more than 11 years of experience in software design and development. He has been involved in web and desktop application developments since the early days of Java. He has also been teacher of computer science courses in the most prestigious education institute in Mexico. His current interests include Groovy and Swing. He is a true believer of open source and has participated in popular projects like Groovy, Griffon, JMatter and DbUnit, as well as starting his own projects (Json-lib, EZMorph, GraphicsBuilder, JideBuilder). Founding member and current project lead of the Griffon framework. He blogs periodically at http://jroller.com/aalmiray. You can find him on twitter too as @aalmiray. He likes to spend time with his beloved wife, Ixchel, when not hacking around.

More About Andres »

NFJS, the Magazine

2011-12-01 00:00:00.0 Issue Now Available
  • BDD and REST

    by Brian Sletten
  • Mocks and Stubs in Groovy Tests

    by Kenneth Kousen
  • Algorithms for Better Text Search Results

    by John Griffin
  • Knowns and Unknowns of Scrum and Agile

    by Brian Tarbox
Learn More »