GORM
Use size instead of length.
Domain property constraints: do not use length, but size. If you use length, you won't be warned at all, but it won't work either. And a book (and a very good one!) by Graeme, the "The Definitive Guide to GRAILS", still uses the "length" in all examples. So, stay warned.
Use right type parent reference when defining one-to-many relationship
When defining a one-to-many relationship, in the child object you have to define a declare it by static belongsTo = Parent, but also you need to define a property that references the parent. Now, this property, has to be of the Parent type. As obvious, as it seems to be, I have spent another couple hours to figure out, why the dynamic views were not reflecting one side of the relationship. Again, there is no warning. It's up to you, so stay alert.
The View
GSP values declared via a tag are strings
Quiz: what does this do?
<g:def var="loop" value = "9"/> <% for (i in 0..loop) { println i } %>
Answer: "9" is a string and the range 0..loop casts "9" to 57.
Resolution: use "${9}"
Controllers
Getter methods are called when controller is created
A controller getter method like the following:
def getFoo() {
...
}
will be called when the controller is created. This is done, in part, to determine which of the controller's properties are Closures since those are the actions the controller can respond to. Several issues can arise. For example, if getFoo() is a resource-intensive method call, this will add to the request processing time anytime getFoo()'s controller is created. Also, exceptions might be thrown if getFoo() references dynamic properties, like servletContext, that are not yet injected into the controller.
Unit testing
Don't call dynamic methods from controller or unit test
First, if you try to call dynamic methods (in controller you have: def scaffold = Book), from your unit tests, you'll get an ugly message, that doesn't help you understand what's the problem. The thing is, you need to switch to static scaffolding in order to be able to call controller methods from unit tests.
Hidden validation error messages
If you have a def book = new Book(title:'Ala ma Kota').save() and the constraints are violated by it, you'll get a null returned from save() as a result. But how to find what is the problem with new Book()? Well, it's a secret. Use book.errors.allErrors to get the list of errors and println on them. And by the way, they will not show up in the unit test stdout. See next bullet for this.
Hidden unit test error log
Unit tests send errors to a file well hidden in <app_base>/target folder.
Grails and the Server
Auto-Reloading after changes
In general, Grails tries to perform (I think, in cooperation with the web app. server) auto-reloading if you perform changes to the application while the application is running. However, if you did some domain modifications and see an error message about Hibernate exception, don't think long: you need to restart the Grails application. And in some cases, you may need to drop the DB tables, if you happen to be using persistent mode of the DB.
Location of Log4j.properties File
When Grails application is deployed to Tomcat, the files log4j.*properties in the grails-all/conf folder are ignored. Only the file in WEB-INF/classes (or whatever is specified in the web.xml) is actually used to configure the log4j logging.
Comments (1)
Apr 30, 2008
Pam Callaway says:
Also on GORM - circular references can cause an error in Grails 1.0.2... http:/...Also on GORM - circular references can cause an error in Grails 1.0.2...
http://jira.codehaus.org/browse/GRAILS-2689