Last updated by
1 year ago
Page: 1.4.0.M1 Release Notes, Version:0
Grails 1.4-M1 Release Notes
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.- Documentation: http://grails.org/doc/1.4.0.M1/
- Changelog: http://jira.grails.org/browse/GRAILS/fixforversion/11040
- Download: Amazon S3
New Features & Improvements
Upgraded Libraries
Grails 1.4 comes with Spring 3.1 M1, Groovy 1.8, Hibernate 3.6, Servlet 3.0 and Tomcat 7.0Reloading Agent
There is a new JVM-agent that handles reloading of classes making it possible to reload changes to domain classes, statically typed services and more cases that weren't supported before.Plugin Usage Tracking
A new optional system for users to report plugin usage is integrated into Grails. The statistics of the most used plugins will soon be published on the Grails website based on this information.Improved Scaffolding UI
There is a new HTML5 enhanced scaffolding UINew Test Report and Documentation Templates
Test reports and documentation look better in Grails 1.4, thanks to new templatesIntegration of the resources plugin into Grails core
The resources is now fully integrated making it even easier to serve websites with optimized static resource handling (caching, gzipping, bundling etc.)Better Unit Testing
The section on unit testing in the user guide has been completely re-written based on new support for unit test mixins that work in JUnit 3, JUnit 4 and Spock (0.6 of spock required).Unit testing has been greatly simplified for all artifact types. Example:// Test class
class SimpleController {
def home() {
render view:"homePage", model:[title:"Hello World"]
}
…
}
void testIndex() {
controller.home() assert view == "/simple/homePage"
assert model.title == "Hello World"
}Abstract Inheritance Support in GORM
GORM now supports abstract inheritance trees which means you can define queries and associations linking to abstract classes:abstract Media { String title … } class Book extends Media {} class Album extends Media {} class Account { static hasMany = [purchasedMedia:Media] }..def allMedia = Media.list()
GORM API now available to Java (and other static languages)
The GORM API is now injected in the bytecode of GORM entities via Groovy transformations. This means many GORM methods are visible and calling from Java code (excuse the semi-colons):Book book = new Book(); book.setTitle("The Stand") book.save();System.out.println(Book.count()); System.out.println(Book.list());
Attributes On link Namespace Tags
Tags in the link namespace now support an attrs attribute.<link:accountDetails attrs="[class: 'fancy']" acctNumber="8675309">Show Account</link:accountDetails>
…
"/details/$acctNumber"(controller: 'account', action: 'showAccount')
...<a href="/details/8675309" class="fancy">Show Account</a>
H2 Database Engine
Grails now includes H2 as the default database for new applications in place of HSQL.Support For Calling Association Named Queries
When a named query involves a domain class relationship and the relationship class defines a named query, that named query may be accessed directly as a method call. An example:class Author { static hasMany = [publications:Publication] static namedQueries = {
authorsWithRecentPublications {
publications {
// invoking a named query defined in the Publication class…
recentPublications()
}
}
}
}class Publication { Author author static namedQueries = {
recentPublications {
def now = new Date()
gt 'datePublished', now - 10
}
}
}Filter Exclusions
Filters may now express controller, action and uri exclusions to offer more options for expressing to which requests a particular filter should be applied.filter1(actionExclude: 'log*') {
before = {
// …
}
}filter2(controllerExclude: 'auth') {
before = {
// …
}
}filter3(uriExclude: '/secure*') {
before = {
// …
}
}Shared Constraints And Command Objects
Command objects now support the application of shared constraints using the same technique previously supported with domain classes.New OrCreate and OrSave Queries
Domain classes have support for the findOrCreateWhere, findOrSaveWhere, findOrCreateBy and findOrSaveBy query methods which behave just like findWhere and findBy methods except that they should never return null. If a matching instance cannot be found in the database then a new instance is created, populated with values represented in the query parameters and returned. In the case of findOrSaveWhere and findOrSaveBy, the instance is saved before being returned.def book = Book.findOrCreateWhere(author: 'Douglas Adams', title: "The Hitchiker's Guide To The Galaxy")
def book = Book.findOrSaveWhere(author: 'Daniel Suarez', title: 'Daemon')
def book = Book.findOrCreateByAuthorAndTitle('Daniel Suarez', 'Daemon')
def book = Book.findOrSaveByAuthorAndTitle('Daniel Suarez', 'Daemon')Automatic Updating of SNAPSHOT dependencies and plugins
Grails now checks for new releases of all dependencies and plugins that have a version number that ends with “SNAPSHOT” and will automatically download the newer version if one is available and install it.Support for permanent (301) redirects
Theredirect() method now accepts a permanent parameter that if true will result in the redirect being issued with a 301 HTTP status code, as opposed to the usual 302 HTTP status code.Breaking Changes and Deprecations in 1.4
- The OpenRicoBuilder has been removed
- The JsonBuilder class deprecated in favour of grails.web.JSONBuilder has been removed
- All static holders are deprecated (ConfigurationHolder, ApplicationHolder, PluginManagerHolder, BuildSettingsHolder etc.)
- Abstract base classes extended by GORM entities must go into src/groovy if they are not to be regarded as persistent
- Criteria query joins are now INNER joins instead of LEFT joins by default
- Public methods in controllers are now treated as actions, so you may want to make those methods private or protected.
- 'count' is no longer a valid domain class property.
- The 'release-plugin' command has been removed - use 'publish-plugin' from the new Release plugin instead.
- The g:resource tag may now throw a FileNotFoundException if the resources plugin is also installed, if the resource you link to does not exist. Without resources framework installed, the URI to the non-existent resource will be rendered.
- The
redirect()method no longer commits the response, allowing extra headers to be added after theredirect()call. Code that relies on response.isCommitted() may break and will need to change to use request.isRedirected() - The withFormat(Closure) method no longer inspects the CONTENT_TYPE header but now deals exclusively with the response format via the file extension, format parameter or ACCEPT header. There is a new request.withFormat(Closure) method to deal with the request format as defined by the CONTENT_TYPE header
- The default
applicationContext.xmlhas changed, so be sure to rungrails upgradeon existing projects.