Colin Harrington

GORM :: override a setter on a Grails Domain

by on Jan.08, 2009, under Groovy-Grails

GrailsRather than implement properties in the Java Language, we have a convention called a Java Bean.  This basically means that properties are implemented with getter and setter methods with a PascalCase property name in the method among a few other simple conventions

Grails makes it incredibly easy to manage domain classes since it is inherently domain-centric.  When you need to enhance your Domain classes at the core of your application, you have an option of implementing your own getters and setters.   I love that by default you do not have to implement your own setters, but you have the power to do so if you wish;  the principle of sensible defaults.  Here is an example of a Book Object with two properties, author and isbn.

class Book {
    String author
    String isbn
}

Consider the case where a Book is in your Database with the ISBN of 978-1430219262 and a user tries to search for "9781430219262".  Unless you do some searchable magic, the user will not find the book.  A simple solution fo the issue would be to never store ‘-’ in the databse.  to make this happen you could easily remove the dash in the setter.  So your domain would look like this:

class Book {
    String author
    String isbn

    void setIsbn(String i) {
        isbn = i.replace('-','')
    }

}

When I first tried this, I failed a few times before I got it right.  Maybe I was just spoiled with Groovy’s groovyness, but I started out writing
def setIsbn(i){ ... }  and when that didn’t work: void setIsbn(i){ ... } which was being called, but never actually set the property.  Then I had a forehead smacking moment where I realized that the method signature must precisely match the signature of a JavaBean setter like public void setPropertyName(Type propVal) { ... }  In my case I had to make sure that the method was public (public by default), has a return type of void (which is not the default behavior of a closure), and the parameter passed in was of the same type as the property (String)

And then I blogged about it — the fourth day.

:,

12 Comments for this entry

  • Mike

    Colin,
    Great post – I’ve struggled with the same thing in the past. One way you can make sure you get the correct method signature is to run javap on a compiled groovy class (before you override the method, of course):

    groovyc Book.groovy
    javap Book
    Compiled from “Book.groovy”
    public class Book extends java.lang.Object implements groovy.lang.GroovyObject{

    public void setIsbn(java.lang.String);
    ….
    }

    You can then copy that method signature directly into your code to and override it to your hearts content.

    (hat tip to http://naleid.com/blog/2008/12/24/groovy-spread-operator-optional-for-properties-plus-a-peek-into-the-sausage-factory/ for getting me interested in javap)

  • adwin

    oh great. i just know that we can override the setter in GORM. THAT’s really usefull since I need to format the date from String to java.util.date (i am not using g:datepicker, but using my own javascript date picker).

    thank you for sharing your knowledge…

  • Paras Jain

    That certainly helps. Thanks for your suggestion. Thanks to Mike too for his insight

  • Marc

    I’m curious, does GORM use the property set when retrieving from the database?

    on a credential domain class I wanting to guard against a password field being set to a non-hashed value… So my initial thinking was to create:

    String password
    void setPassword(String pw) {
    password = getHash(pw,salt)
    }

    but if the hashed password was retrieved from the database wouldn’t it end up going through another cycle of hashing?

  • danny

    Thanks! This just saved me time. I, like you, tried def setIsbn(i){ … } to find nothing doing.

  • matt

    Ditto danny’s comment. Thanks for saving me a big headache.

  • John

    Thanks Colin!

    A quick Google search and I found this post and the answer to my problem too. To answer Marc’s question, YES – the setters are called when the domain class is being populated so your idea won’t work. What I used as a workaround was to create a service class and add an updateEvent() method which is called from the beforeInsert and beforeUpdate. In the event, I check to see if the value is dirty and only manipulate it if it has.

    if ( user.isDirty(‘password’) && task.getPersistentValue(‘password’) != user.password) { … }

    I check that it is dirty and also that the newly set value is different from the persisted value as a safety precaution.

    -John

  • Jeff

    Solved my problem! (Doh!!!)

  • Kaci Mans

    Hey There. I found your blog using msn. This is a really well written article. I will be sure to bookmark it and come back to read more of your useful information. Thanks for the post. I’ll certainly return.

  • hurtig lån online

    I don’t really like livejournal or xanga. I already have both of those. I was going to try deadjournal because I read on here that it was really good, but I don’t want to have to pay for it and you have to have an invite code to get in free. Does anybody have an invite code they could give me, or a suggestion on another free blogging website I could try? Any information would be helpful..

  • http://www.pimia.pl

    Often we hear experts in the media that report a specific
    stock is gonna soar and now is the time to purchase.
    The truth is, people join MLM opportunities because of who introduced them.
    ” Employees at Nike are encouraged to be curious and open to new ideas, whatever their source.

    Feel free to surf to my blog post: http://www.pimia.pl

  • www.hauori.com

    Furthermore, my experience also includes identifying the competitive advantage
    for the few different companies and crafting that advantage into a online marketing strategy to
    develop new business. Businesses will be to heavily determined by customers for their survival,
    without customers an enterprise would cease to exist.
    The business degree raises one’s social standing:
    in short, it opens for you personally doors that will have
    otherwise remained closed for you.

    Feel free to surf to my homepage http://www.hauori.com

1 Trackback or Pingback for this entry

Leave a Reply

Looking for something?

Use the form below to search the site:

Still not finding what you're looking for? Drop a comment on a post or contact us so we can take care of it!