Your Grails domain class has more properties than you think!

June 10, 2008 – 4:32 pm

But you probably already knew that - things like ‘id’, ‘version’ and ‘log’ properties are added to every Grails domain class by the framework and are pretty obvious.  But there are a few more that might not be so familiar.

Take a look at this domain class:

class Book {
    String name
    Author author
}

Of course, it has a name and author, and a few more - if I print out new Book().properties.each {println it} the following are revealed (check out the one in bold):

  • author:null
  • authorId:null
  • class:class Book
  • constraints:… (removed for brevity)
  • errors:org.springframework.validation.BeanPropertyBindingResult: 0 errors
  • id:null
  • log:org.apache.commons.logging.impl.Log4JLogger@de9e85
  • metaClass:groovy.lang.ExpandoMetaClass@47ec8e[class Book]
  • name:null
  • version:null

I guess I understand where this is coming from (since Book has an Author) - but it tripped me up a little bit the other day when I was working with a domain builder.  The builder is pretty ‘dumb’ - it basically builds domain classes based on attributes of a map that match up with attributes on a domain class.  So along came a new domain class:

class Author {
    String name
    String authorId
}

which just happens to contain an ‘authorId’ (users wanted to capture an ID separately from the ID Hibernate generates).  When the builder checks the properties against the two domain classes - it finds a match in the Book class because of the ‘authorId’ property and tries to set it - but BOOM!  ’authorId’ is a read-only property (as it should be).  No worries, it’s a quick fix - now the builder just checks to see if the property also has a setter - something like if(dc.metaClass.hasProperty(dc, it)?.setter) - and TADA, we’re back up and running.

Anyway, the next time you’re playing around in Grails console - give it a shot and take a look at the properties your domain classes have - you might be surprised what you find.

The elusive HTML ‘id’ attribute when using <g:form>

April 14, 2008 – 1:07 pm

In most Grails tags, the usual HTML attributes get passed through to the output HTML, for example the ‘class’ attribute below:

<g:textField name="name" class="inputField" value="${book?.name}" />
results in:
<input type="text" class="inputField" name="name" value="" id="name" />

I tried to do this with a g:form tag and passed in an “id” attribute so I could reference the form in javascript. But you can’t pass an id attribute to the g:form tag because the “id” attribute is reserved for the id of the domain object you’re dealing with:

<g:form action="save" method="post" id="bookForm">
results in:
<form action="/form/book/save/bookForm" method="post" >
instead of this (like what I was hoping for):
<form action="/form/book/save" method="post" id="bookForm">

As a workaround I abandoned the g:form tag whenever I needed to pass through an “id” attribute and just wrote a standard HTML <form> tag instead…until I noticed that the “name” attribute of g:form is also output as the “id” in the generated HTML. So now, I just write a g:form tag with a “name” attribute and end up with the result I’m looking for! Here’s the example:

<g:form action="save" method="post" name="bookForm">
results in:
<form action="/form/book/save" method="post" name="bookForm" id="bookForm" >

“bookForm” shows up in the HTML code as both the name and the id of the HTML form tag.

Using the showSource parameter trick with rendered templates

March 31, 2008 – 12:19 pm

This is a follow-up to my previous post about using the showSource parameter in Grails.

If you’re using templates to keep DRY, you may need to pay attention to the details of the stack trace that show which GSP contains the error. For instance, say my show.gsp renders a template like this:

<g:render template="/person/personDetails" bean="${person}"/>

If there’s an error with the _personDetails.gsp, adding showSource to the URL of “show” (like this: http://localhost:8080/[APP_NAME]/person/show/1?showSource) won’t actually do the trick. That will show you the source of the show.gsp page, not the _personDetails.gsp page. Look closely at the stacktrace and you’ll see the actual path to the GSP that threw the exception - in this case it’s grails_app_views_person__personDetails_gsp (which translates to grails-app/views/person/_personDetails.gsp). If you change the URL to point directly at the GSP in question and then append the showSource parameter, (e.g. http://localhost:8080/[APP_NAME]/person/_personDetails.gsp?showSource) you’ll get the GSP source you’re looking for.

Viewing the source of a compiled GSP in Grails

March 15, 2008 – 3:55 pm

So you’re working happily on your Grails application, coding away, being extremely productive until BOOM! You get a Grails Runtime Exception error page like this when you hit a GSP:

grails runtime error

What the heck? Reading the stack trace you see that the exception is caused somewhere in a GSP:

You’ve found the error of course, it’s right there on line 33 of the grails-app/views/person/show.gsp. Um, not quite. If you look at line 33 of show.gsp you won’t find anything of consequence:

<td valign=”top” class=”name”>Name:</td>

There isn’t any code on that line that could possibly cause a null pointer exception. So then you realize - the line 33 the stack trace is referring to is the line in the compiled GSP! But where oh where would that source for the GSP be? You search in your ~/.grails directory but don’t find anything obvious there. A couple fruitless google searches later and you start undoing your changes, one by one, until you find the line of code that caused your problem. What if, you ask, there was an easy way to see the source of a compiled Grails GSP? Then you find out:

there is.

When running in “development” mode (i.e. this trick doesn’t work in test or production or other environments), just append the parameter “showSource” to the URL (e.g. http://localhost:8080/[APP_NAME]/person/show/3?showSource) and TADA - you get the compiled source code:

Now you can figure out where line 33 is (I usually end up copying the source into an editor like TextMate that shows line numbers) and see what caused your error. In this particular case, gender is null and when the GSP tries to obtain the “code” attribute on the “gender” property, it causes a NPE.

Add a quick fix:
person.gender?.code
try the page again and everything’s hunky dory.

Thank you showSource parameter. You just made my life oh so much easier.

Accurate branch reports with Grails and Cobertura _1.8_

January 31, 2008 – 8:35 pm

I’m trying to figure out why Cobertura coverage reports on my Groovy and Grails code don’t show the branch coverage that I expect they should. I noticed that at some point in the past, Cobertura did show a correct branch report. So I tried the grails code-coverage plugin with Cobertura version 1.8:

100% Branch Coverage

TADA! Now the reports are showing the coverage I expect. I know Cobertura (version 1.9) improved on the way it calculates branch coverage (see the news item from 5 June 2007 on the Cobertura website) but for my purposes, Cobertura 1.8 gives me more of the information that I need. I’m mostly concerned with finding code that isn’t tested at all, and that’s hard to do when almost every line of code is highlighted in red like version 1.9 was doing:

Branch Coverage on StateController

So for now I’ve updated the Grails code-coverage plugin to utilize Cobertura 1.8. I can live without the new features that 1.9 offers and in the meantime I’ll work with the cobertura-devel folks to see if there’s something that we can improve for a future release.