Last updated by admin 9 years ago

0.5 Release Notes

30 April 2007

The Grails development team has reached another milestone and is pleased to announce the release of version 0.5 of the Grails web-application development framework.

Grails is a dynamic web-application framework built in Java and Groovy, leveraging best of breed APIs from the J2EE sphere including Spring, Hibernate and SiteMesh. Grails brings to Java and Groovy developers the joys of convention-based rapid development while allowing them to leverage their existing knowledge and capitalize on the proven and performant APIs Java developers have been using for years.

Development has been intense since the release of 0.4.2 at the end of February, tackling over 190 issues in this period. This release has seen exciting contributions from new team members and users and significant functionality enhancements.

Thank you to all the team members, patch contributors and users. A lot of hard work has gone into this release - we hope you enjoy using this latest installment of the Grails adventure.

New Features

  • Custom URL Mappings
  • Command objects / form validation
  • List & Map support in GORM
  • Support for composition in domain class (Hibernate "components")
  • Base64 codec
  • Dependency resolution with Ivy
  • Project metadata and versioning support, smarter scripts and upgrade processes
  • Script event hooks
  • Automatic addition of log objects to all artefacts
  • New Artefact API available to Plugins


  • Major improvements to artefact reloading
  • Improved relationship management methods in GORM
  • Cascading validation
  • Retrieving multiple objects with Book.getAll(1,2,3)
  • Using named HQL parameters in find() methods
  • Clean up of some legacy constraints issues
  • Performance improvements (40-50% faster)
  • Taglib optimisations
  • Improvements to scaffolding (sortable columns, pagination of large resultsets, etc.)
  • I18N improvements
  • Overhauled GSP view loading
  • Even greater test coverage of the core Grails code
  • Many many bug fixes

Detailed examples

Custom URL Mappings

You can now create a URL mapping class that uses, for those interested, a dynamic builder/metaclass mechanism to map the URI space of your application to your controllers and actions in almost any way you like. You can pull out parts of the URL as variables and even apply constraints to these.

On top of this, grails taglibs that produce links are smart and will reverse map controller/action combinations to URLs from the mappings, so links generated within your pages are consistent with your public URL interface defined in your mappings.


class MyUrlMappings {
  static mappings = {
    "/product/$id" {
         controller = "product"
         action = "show
    "/$id/$year/$month/$day" {
         controller = "blog"
         action = "show"
         constraints {

This removes the necessity to use something like Apache's mod_rewrite to produce user-friendly URLs or to abstract your URL space away from your implementation.


Command Objects / Form validation

Grails has always had domain class constraints, but often a form or request parameters do not relate directly to a domain class. New in 0.5, command objects are automatically created and populate by Grails when the request is received, and validated against database-like constraints, before your action is even called.


class LoginController {
  def login = { LoginCommand cmd ->
         if(cmd.hasErrors()) {
         else {
            // do something else

class LoginCommand { String username String password static constraints = { username(blank:false, minSize:6) password(blank:false, minSize:6) } }

Any Groovy class can be used as a command object, with the standard Grails property binding and validation options. You just specify the typed parameters to the action closure and Grails works out the rest!


List & Map support in GORM

GORM has been enhanced to support lists of domain objects in a relationship, as opposed to the default Set behaviour, providing ordered lists.

// Support for Lists of objects
class Author {
  List books
  static hasMany = [books:Book]

author.books[0] // get the first book

There is also support for Maps of standard non-domain types:

// Support for Maps of objects
class Author {
  Map books // map of ISBN:book names

def a = new Author() a.books = ["1590597583":"Grails Book"] well as maps of standard type keys to domain objects:

// If you want a map of domain classes you  can do
class Book {
 Map authors
 static hasMany = [authors:Author]

def a = new Author(name:"Stephen King")

def book = new Book() book.authors = [stephen:a]


Support for composition in domain class (Hibernate "components")

By default GORM currently uses table-per-hierarchy mapping of classes to the database, which means that classes in relationships typically are stored in a separate table.

You now can use the Hibernate composition mechanism to embed the data from objects that would otherwise be considered relationships, within the main table used for the outer class, using the "embedded" declaration.

class Address {
	String street
	// …
    String country

class Person { String firstName String lastName

Address homeAddress Address workAddress

static embedded = ['homeAddress', 'workAddress'] }

The "embedded" property is set to the list of property names that represent complex properties that should be written into the table directly instead of forming a relationship.


Base64 codec

Augmenting the existing super-useful codecs supplied in 0.4, we have now added a Base64 codec so that you can now write code such as this anywhere in your Groovy code or GSPs:

Your registration code is: user.registrationCode.encodeAsBase64()


Dependency resolution with Ivy

We've added support for Ivy dependency resolution for your projects. There are two new targets for this:

grails install-ivy

With the above run once per-project, you can then execute:

grails get-dependencies

To update your project's dependencies.

Project metadata and versioning support, smarter scripts and upgrade processes

The days of accidentally running with the wrong Grails version for your project are gone with 0.5 and future versions. Applications have metadata stored in a file (not generally for user editing) that includes the required version of grails, and a version number of your application.

Most of the grails targets therefore refuse to run if the grails version you are using in GRAILS_HOME does not match that of the project, so that you never omit to run grails upgrade.

Your application's version number is now included in the filename of generated war files. You can set the version number with "grails set-version"

Furthermore, you can now override the name used for your application so that it does not use the parent directory name.

Script event hooks

A new event mechanism allows target scripts, even those in plugins and your custom application scripts, to fire and respond to events. By default we have events for artifact and file creation, plugin installation, script shutdown, and progress notifications. This allows, for example, integration with Growl on Mac OS X to provide on-screen notifications when grails tasks complete.


Automatic addition of log objects to all artefacts

Version 0.4 added an implicit "log" object for controllers. We have now expanded this feature to all artefact classes in the application. This means that all domain classes, services, jobs, controllers and so on (all declared artefacts using the artefact API) receive an implicit log object of their own.

The logs are named in such a way that you can controll the logging of individual artefacts or the category of artefacts they belong to, or all of your artefacts in the application.


New Artefact API available to Plugins

The internal artefact mechanisms have been overhauled to allow plugins to register first-class artefacts of their own that will be managed just like all other grails artefacts, and receive implicit log objects and other features.



Major improvements to artefact reloading

Automatic reloading of modified code at runtime is a major productivity boost, and one of the most enjoyable parts of using Grails versus traditional Java web-application development. In this release we added support for reloading of domain classes, transactional services and Quartz jobs.

Improved relationship management methods in GORM

Along with some of our users, we thought that the implicit addXXXX methods in 0.4 were nice but bit clunky when you had multiple relationships of the same type. We've sorted this out for 0.5 and are proud to introduce the minor but important change from addXXXX to addToXXXX methods, where the latter new form takes the name of the property (collection) not the type of the relationship:

def a = new Author(name:"Stephen King")
            .addToBooks(title:"The Stand")


You will also notice we now have the orthogonal removeFromXXXX which manages the bi-directional references if they exist.


Cascading validation

Validation constraints are now applied to all related objects in the object graph when persisting or validating a domain object.

Retrieving multiple objects with Book.getAll(1,2,3)

A new method was added for retrieving multiple objects in one call.

Using named HQL parameters in find() methods

There is now support for positional and named parameters in HQL queries.

Clean up of some legacy constraints issues

We've finally removed the "optionals" property and nullability is purely controlled by the nullable constraints, and the often duplicated functionality between length and size constraints is being phased out, with the size variants being the future path.

Performance improvements (40-50% faster)

It's early days for Grails performance tuning - we make it work first and optimize as necessary later. However we've added some important optimisations in this release to improve first load time and also runtime performance.

Taglib optimisations

Specific optimisations related to taglibs should see significant request throughput increases where pages use many GSP tags.

Improvements to scaffolding

As part of our ongoing effort to increase the real-world usefulness of scaffolding, we have added sortable columns, improved pagination of large result sets, and other improvements to the default scaffolding templates.

I18N improvements

Message bundles are reloadable and we have support for more languages out of the box including Russian, German and Spanish. There have also been changes to some default message codes used, to make them more logical.

Overhauled GSP view loading

View resolution has been re-written to use a resource loader mechanism.