Saturday, November 7, 2009

Grails and JSON are pretty Groovy!

Once again the incredible productivity boosts provided by Grails have become glaringly obvious.... what is it this time???? Dealing with JSON!!

In my project I needed to save domain info to files and these domains contained domains so I thought the easiest way would be XML and JSON.... having done some work in XML in Grails I decided to see how I fared in JSON.

Here's what happened:


import grails.converters.*

def report = MyDomain.get(1)
def json = ""
JSON.use("deep") {
def converter = report as JSON
converter.prettyPrint = true
json = converter.toString()
}



First off I grab a domain instance and then convert it to JSON using grails.converters.JSON. Note that grails.converters.deep is deprecated so to render your domain "deeply" you must use the configuration name "deep". I also grab the converter so I can alter some settings, specifically prettyPrint. This will render your domain in nicely formatted JSON!

So now I have a JSON string, how can I access its properties.... do I have to parse it by hand???? Fat chance...



def jsonArray = JSON.parse(json)

println jsonArray.myDomainProperty



So now we use JSON.parse() to convert our json String to an object that allows us to access our domain properties... sweet!

So there we have it, domain to json and back to an object that we could, if we wanted to, convert back to a domain...

Hope this saves people some time. Parsing and creating JSON???? Let Grails do the work...... again! :)

Wednesday, September 30, 2009

Grails Constraints Across Relationships

Holy Moley am I glad to see the back of this problem!

This blog post is a summary of an issue I raised on the Grails User mailing list, here, and let me first give thanks to Dave Klein and Daniel Honig who really helped in figuring out this issue and explaining it to me, even though the time difference meant I could not stay awake any longer :)

OK so, suppose we have the following domains:


class Parent {

static hasMany = [children: Child]

String name;

static constraints = {
}
}



and ...



class Child {
static belongsTo = [parent: Parent]

String name

static constraints = {
name nullable: false, blank: false
}
}



Here we can see typical one to many relationship which allows me (you) to do the following in say, a Grails Service:



def parent = new Parent(name:"Father")
def billy= new Child(name:"Billy")
parent.addToChidren(billy)
parent.save()



So what happens here? We create a Parent, add a child to it, call save() on the parent and because the child "belongsTo" the parent, the child instance is saved too. That's just good parenting in my opinion!

OK so, our Parent doesn't want to be confused and have 2 children with the same name, nothing wrong with this, it's just this parents preference! So the knee-jerk reaction is to add a "unique:true" constraint to the Child domain.... hmmm wait a minute, if we do this, this means that we can only have one child named "Billy" in the entire world, hmmm that wont work. So thinking about it again, we want the Child's name to be unique only for a specific parent, so maybe we do something like "unique:'parent'" on the name property of the Child domain. If we do this, our Child domain becomes:


class Child {
static belongsTo = [parent: Parent]

String name

static constraints = {
name nullable: false, blank: false, unique: 'parent'
}
}


OK so, now lets start afresh:


def parent = new Parent(name:"Father")
def billy= new Child(name:"Billy")
def robert= new Child(name:"Robert")
parent.addToChidren(billy)
parent.addToChidren(robert)
parent.save()


Uh oh, something has gone wrong, I am now getting this madness when i try to save(): "InvalidDataAccessApiUsageException: object references an unsaved transient instance - save the transient instance before flushing: Parent".... Hmmm, something is not quite right here.

After some very good debugging from the aforementioned Groovynauts, it was discovered that Grails needed the Parent to be persisted before proper validation could take place on the children. This is only a minor annoyance if we wrap the code in a withTransaction{} block, why you ask? If we use a withTransaction block we can save our Parent confident in the fact that if any constraints fail on our children (or something else goes wrong) we will not have Parents in our database missing their children. Grails will roll back and remove the Parent from the database for us. So here it is (place this in a service method for instance):


Parent.withTransaction{
def parent = new Parent(name:"Father")
parent.save(flush:true)

def billy= new Child(name:"Billy")
def robert= new Child(name:"Robert")
parent.addToChidren(billy)
parent.addToChidren(robert)
parent.save(flush:true)
}


And there we have it, no parent can have multiple children that have the same name! For more info on how this was all figured out, check the link to the user list above, also check here for how to do something like this in a single domain and not across relationships.

Oh and if you do attempt to add children with the same, a "org.springframework.dao.DataIntegrityViolationException" is thrown!

Thanks again to the grails community! I hope someone finds this blog useful and doesn't lose as may hours (days?) as i did :)

Oh and one more thing, if you add unique:'parent' after you have done some dev work, i.e. your database is already built, you may need to rebuild the database as MySql did not update the indexes for me, might save some more confusion!

Tuesday, August 4, 2009

Pretty Printing Groovy's StreamingMarkupBuilder

Unfortunately, Groovy's StreamingMarkupBuilder will not output indented xml due to its streaming nature. However, never fear, JTidy is here to save the day!

JTidy is a project hosted here on sourceforge and it is a pretty nice HTML/XML pretty printer. It also seems to check your HTML for errors, which is cool! Examples are lacking however so I thought I would share my findings with this example:


public class JTidyExample {

def tidyMeUp(String singleLine) {
StringWriter writer = new StringWriter()
Tidy tidy = new Tidy()
tidy.identity {
setEscapeCdata(false)//leave cdata untouched
setIndentCdata(true)//indent the CData
setXmlTags(true)//working with xml not html
parse(new StringReader(singleLine), writer)
}
writer.toString()
}

def createMarkUp() {
String cData = "<![CDATA[hello]]>"
StreamingMarkupBuilder xml = new StreamingMarkupBuilder();
def person1 = {
person(id: 1) {
firstName("John")
lastName("Doe")
data_labels {
mkp.yieldUnescaped(cData)
}
}
}
def personList = {
people {
out << person1
}
}
xml.bind(personList).toString()
}

def static main(def args) {
def example = new JTidyExample()
def singleLine = example.createMarkUp()
println "Before: \n ${singleLine}"
println "After: \n ${example.tidyMeUp(singleLine)}"
}

}



The following is output:


Before:

<people><person id='1'><firstName>John</firstName><lastName>Doe</lastName><data_labels><![CDATA[hello]]></data_labels></person></people>

Tidy (vers 26-Sep-2004) Parsing "InputStream"
no warnings or errors were found

After:

<people>
<person id='1'>
<firstName>John</firstName>
<lastName>Doe</lastName>
<data_labels>
<![CDATA[hello]]>
</data_labels>
</person>
</people>



Here we can see that our XML is now nicely indented. Want some more??? Check out Scott Davis' Groovy Recipes, it has a pretty sweet XML section!

UPDATE: Check out Paul Kings comments where he suggests using groovy.xml.XmlUtil.serialize(xml.bind(personList)). Sweet!

Friday, July 24, 2009

Grails Transactions In Brief

OK so first ever blog post, lets keep things short!

I was playing around with transactions in Grails as part of a project a while ago, bearing in mind I have no Spring experience, I was a little worried it might be complicated. Need I worry??? Lord no! Grails to the rescue once again, however there is one 'Gotcha' that I feel is worth putting out there, hence me writing this 'blog'.

Basically transactions are a facet of Grails (obtained from Spring I think) that allow us to roll back database writes if an exception occurs mid-method making our databases cleaner than.... hmm.. don't want to write an offensive metaphor in my first post so lets leave it at clean :)

Suppose we have the following method in our service:

static transactional = true

def serviceMethod(params1,params2){

def domain1 = new Domain()
domain1.save()

def domain2 = new Domain()
domain2.save()//Exception thrown here
}




So because this is transactional, when the exception is thrown while saving domain2, domain1 should be deleted from the database (well that was my assumption). However this is NOT the case. After some reading, it seems that the roll back will only occur if the exception thrown is of type RuntimeException. This means that we would have to catch an exception and then throw a RuntimeException, which I think makes this sort of transactional behavior pointless... if we know where exceptions are going to occur we could just roll back ourselves maybe.... I'm sure there's a reason :)

However, all is not lost!! We can take finer grained control of transactions using the Domain.withTransaction{} closure where Domain is the name of a domain in our project. To use this, we must set the service's transactional property to false. Here's how it works:


static transactional = false

def serviceMethod(params1,params2){

Domain.withTransaction{tx ->

def domain1 = new Domain()
domain1.save()

def domain2 = new Domain()
domain2.save()//Exception thrown here

}

}


Now when any exception is thrown at domain2.save() (probably before it), the transaction is rolled back and domain one is deleted. We can also roll back programmically by using tx.setRollbackOnly(). Actually saying domain one is deleted probably isn't correct because they are never persisted, just saved to the session... i think!

Anyways, I hope this helps some people new to dealing with transactions in Grails. Feedback is welcome and also if anyone knows how to make my source code indent properly, by all means share :)

John