(Quick Reference)

1.4.4 Persistence Features - Reference Documentation

Authors: Graeme Rocher, Peter Ledbrook, Marc Palmer, Jeff Brown, Luke Daley, Burt Beckwith, Lari Hotari

Version: 2.3.8

1.4.4 Persistence Features

The GORM API

The GORM API has been formalized into a set of classes (GormStaticApi, GormInstanceApi and GormValidationApi) that get statically wired into every domain class at the byte code level. The result is better code completion for IDEs, better integration with Java and the potential for more GORM implementations for other types of data stores.

Detached Criteria and Where Queries

Grails 2.0 features support for DetachedCriteria which are criteria queries that are not associated with any session or connection and thus can be more easily reused and composed:

def criteria = new DetachedCriteria(Person).build {
    eq 'lastName', 'Simpson'
}
def results = criteria.list(max:4, sort:"firstName")

To support the addition of DetachedCriteria queries and encourage their use a new where method and DSL has been introduced to greatly reduce the complexity of criteria queries:

def query = Person.where {
    (lastName != "Simpson" && firstName != "Fred") || (firstName == "Bart" && age > 9)
}
def results = query.list(sort:"firstName")

See the documentation on DetachedCriteria and Where Queries for more information.

New findOrCreate and findOrSave Methods

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')

Abstract Inheritance

GORM now supports abstract inheritance trees which means you can define queries and associations linking to abstract classes:

abstract class Media {
    String title
    …
}
class Book extends Media {
}
class Album extends Media {

} class Account { static hasMany = [purchasedMedia:Media] }

..

def allMedia = Media.list()

Multiple Data Sources Support

It is now possible to define multiple datasources in DataSource.groovy and declare one or more datasources a particular domain uses by default:

class ZipCode {

String code

static mapping = { datasource 'ZIP_CODES' } }

If multiple datasources are specified for a domain then you can use the name of a particular datasource as a namespace in front of any regular GORM method:

def zipCode = ZipCode.auditing.get(42)

For more information see the section on Multiple Data Sources in the user guide.

Database Migrations

A new database migration plugin has been designed and built for Grails 2.0 allowing you to apply migrations to your database, rollback changes and diff your domain model with the current state of the database.

Database Reverse Engineering

A new database reverse engineering plugin has been designed and built for Grails 2.0 that allows you to generate a domain model from an existing database schema.

Hibernate 3.6

Grails 2.0 is now built on Hibernate 3.6

Bag Collections

You can now use Hibernate Bags for mapped collections to avoid the memory and performance issues of loading large collections to enforce Set uniqueness or List order.

For more information see the section on Sets, Lists and Maps in the user guide.