Last updated by 4 years ago

Page: 1.2-M2 Release Notes, Version:8

Grails 1.2-M2 Release Notes

11th of August 2009

SpringSource are pleased to announce the 1.2 Milestone 2 release of the Grails web application development framework.

Grails is a dynamic web application framework built on Java and Groovy, leveraging best of breed APIs from the Java EE 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.

Further information about the release can be obtained using the links below:

New features in 1.2 Milestone 2 are described below. The objectives for Milestone 3 are standalone GSP, web flow extracted to a plugin and further incremental improvements to core.

New Features

Spring 3 Upgrade

Grails 1.2 Milestone 2 is the first release featuring the latest Spring 3 codebase. As of this release Grails now also supports Spring annotation prototypes through component scanning such as @Service, @Component etc.

Any class can be annotated with @Component and will automatically become a Spring bean injectable in other classes.

In addition you can annotate classes with @Controller and these will be able to handle requests just like regular Spring MVC controllers, thus providing support for those wanting to use a combination of Spring MVC and Grails:

@Controller
class SpringController {

@Autowired SessionFactory sessionFactory

@RequestMapping("/hello.dispatch") ModelMap handleRequest() { def session = sessionFactory.getCurrentSession() return new ModelMap(session.get(Person, 1L)) }

}

In this example, going to /hello.dispatch will execute the handleRequest() method and atempt to render either a GSP or JSP view at grails-app/views/hello.(jsp|gsp)

URI Re-writing onto any URI

You can now re-write any request URI onto any other URI using the following syntax in your grails-app/conf/UrlMappings.groovy file:

"/hello"(uri:"/hello.dispatch")

This feature can be used to provide pretty URIs for Spring MVC controllers (see above) or static resources.

Per-method transactions with @Transactional

Building on the component scanning features you can now use the Spring org.springframework.transaction.annotation.Transactional annotation on Grails service classes to configure transaction properties and have per-method transaction definitions:

import org.springframework.transaction.annotation.*

class BookService {

@Transactional(readOnly = true) def listBooks() { Book.list() }

@Transactional def updateBook() { // … } }

Improved Dynamic Finders for Boolean properties

GORM dynamic finders have been improved with an easier notation for handling boolean properties. For example given a domain class of:

class Book {
   String title
   String author
   Boolean paperback
 }

You can do:

def results = Book.findAllPaperbackByAuthor("Douglas Adams")

or

def results = Book.findAllNotPaperbackByAuthor("Douglas Adams")

In this case the boolean value is implicitly inferred from the method signature.

Named Query Support

GORM now supports defining named queries in a domain class. For example, given a domain class like this:

class Publication {
   String title
   Date datePublished

static namedQueries = { recentPublications { def now = new Date() gt 'datePublished', now - 365 }

publicationsWithBookInTitle { like 'title', '%Book%' } }

}

You can do:

// get all recent publications…
def recentPubs = Publication.recentPublications()

// get all recent publications (alternate syntax)… def recentPubs = Publication.recentPublications.list()

// get up to 10 recent publications, skip the first 5… def recentPubs = Publication.recentPublications(max: 10, offset: 5) def recentPubs = Publication.recentPublications.list(max: 10, offset: 5)

// get the number of recent publications… def numberOfRecentPubs = Publication.recentPublications.count()

// get a recent publication with a specific id… def pub = Publication.recentPublications.get(42)

Support for hasOne mapping

GORM now supports hasOne mapping where the foreign key is stored in the child instead of the parent association. For example:

class Person { 
	String name 
	static hasOne = [address: Address]
}
class Address {
	String street
	String postCode
}

In the above case a foreign key column called person_id will be created in the address table rather than the default where an address_id is created in the person table.

Strict Validation Errors

There is a new failOnError argument available on the save() method that will throw an exception if a validation error occurs:

try {
     book.save(failOnError:true)
}catch(ValidationException e) {
   // handle
}

Precompilation of Groovy Server Pages in WAR deployment

GSPs are now pre-compiled when producing a WAR file meaning less permgen space is used at deployment time for Grails applications.

Improved handling of i18n class and property names

You can now put entries in your i18n messages.properties file for all class and property names in your application. For example:

book.label = Libro
book.title.label = Título del libro

These are then picked up by Grails' default error messages and scaffolded views.

Tomcat & Multiple Embedded Containers Supported

Grails now supports multiple embedded containers with Tomcat being the default. Grails will by default install the Tomcat plugin into your application. You can easily switch containers by switching plugins:

grails uninstall-plugin tomcat
grails install-plugin jetty

Named URL Mappings

Grails now supports named URL mappings and associated dynamic tags for view layer URL rewriting. For example:

name productDetail: "/showProduct/$productName/$flavor?" {
          controller = "product"
          action = "show"
      }

The above creates a named URL mapping called "productDetail" this can be linked to from the view with:

<link:productDetail 
       productName="licorice" 
       flavor="strawberry">Strawberry Licorice</link:productDetail>

Project Documentation Engine

The same documentation engine that powers the Grails reference documentation is now available in your projects. Simply create your documentation inside the src/docs/ref and src/docs/guide directories of your project. See the Grails documentation source for an example.

Plugin Metadata Generator

When releasing a plugin into the Grails central repository metadata is generated about the methods and properties added to Grails classes at runtime.

This metadata is put into the plugin.xml descriptor and can be read by IDEs and documentation engines.

If your plugin doesn't add methods at runtime you can skip the metadata generation process by doing:

grails release-plugin --skipMetadata