6

I have some code that I want to run when a domain class object is created; in Java, I would include this code on the constructor. How can I do it in Groovy/Grails?

Thanks.

dmahapatro
  • 49,365
  • 7
  • 88
  • 117
user2624442
  • 95
  • 2
  • 6
  • Do you want this custom initialization to happen when instances are created by Hibernate (from the DB), or when (transient) instances are created programatically with `new`? – Dónal May 27 '14 at 08:34

3 Answers3

6

You can add a constructor to domain class but you also have to add the default no-arg constructor if it is not already present.

//Domain Class
class Author {
    String name

    Author() {
        //Execute post creation code
    }

    Author(String _name) {
        name = _name

        //Execute post creation code
    }
}

On the other hand, domain classes are POGOs so you can also use the map constructors if there is no extra logic that needs to be executed on object creation. Without adding any constructors you can also instantiate Author as:

Author(name: 'John Doe')
dmahapatro
  • 49,365
  • 7
  • 88
  • 117
  • Thanks, but how could I keep being able to instantiate the object with a map and still have some code for the constructor? – user2624442 May 27 '14 at 01:07
  • We cannot override the map constructor in the domain class itself, because the map constructor is added to the metaClass of a groovy Class (in this case a grails domain class). But you can override the constructor on the metaClass as [shown here in this blog](http://burtbeckwith.com/blog/?p=1003). You have to add that logic in `BootStrap.groovy` for that particular domain class. – dmahapatro May 27 '14 at 01:34
  • 1
    You use the power of groovy Meta Programming !! no constrcutor to be defined just call the the domian with a constrcutor... – Develop4Life May 27 '14 at 09:26
  • @danielad i really wish java had that feature. Eclipse autogeneration does the trick, but groovy's is so much more easy. – Abe May 27 '14 at 15:55
3

Have you seen this page about groovy constructors? I have had success adding map constructors to Grails domain classes using this technique.

This article contains a good example and highlights an important issue. If you want to disable the map constructor for a Grails domain class (not that I think that's a particularly good idea), you might try throwing a runtime exception rather than returning a new instance. Or, have your map constructor marshall the data and call one of your other constructors.

chim
  • 8,407
  • 3
  • 52
  • 60
augustearth
  • 281
  • 2
  • 10
0

Depending on the exact use case you could use the GORM events ...

http://docs.grails.org/3.1.1/guide/single.html#5.5.1

So you could use

def beforeInsert() {
    doMyCustomThing()
}

def onLoad() {
    doMyCustomThing()
}

There are a few other options, including Hibernate events and custom GORM events

chim
  • 8,407
  • 3
  • 52
  • 60