Groovy & Grails: Domain Classes and GORM
Domain Classes Model Your Data
A domain class describes a table in your database. The class name becomes the table name, each property becomes a column, and each instance becomes a row. GORM, the Grails Object Relational Mapping layer, handles that translation: you work with objects and GORM writes the SQL.
class Book {
String title
String author
Integer pages
static constraints = {
title blank: false
author blank: false
pages nullable: true
}
}The constraints block declares validation rules. title and author cannot be blank, and pages may be null. GORM uses these constraints to validate before saving and to feed generated error messages to the views.
Saving and Reading with GORM
Persistence methods live directly on the domain class. Creating and storing a book takes two lines.
def book = new Book(title: "Dune", author: "Herbert", pages: 412)
book.save()save() validates and inserts the row. Reading data uses the dynamic finder style: readable method names turn into queries.
def allBooks = Book.list()
def one = Book.get(1)
def sciFi = Book.findByAuthor("Herbert")
def thick = Book.findAllByPagesGreaterThan(300)Dynamic finders are generated at runtime from the property names, so findByAuthor and findAllByPagesGreaterThan work without you writing query strings by hand.
Relationships
Real apps need links between tables. GORM supports the usual relationships with simple declarations.
class Author {
String name
static hasMany = [books: Book]
}
class Book {
static belongsTo = [author: Author]
}hasMany says one author owns many books, and belongsTo ties the book to its author and controls cascade saves. The generated schema includes an author id column on the books table automatically.
Why This Matters
The database remains a normal relational database that you can inspect with SQL. GORM only sits on top, so raw queries and migrations stay available when you need them.
Key Points
- Domain classes map to tables, properties to columns, instances to rows.
- The constraints block validates data before it reaches the database.
- save, list, get, and dynamic finders cover everyday persistence.
- hasMany and belongsTo express relationships with minimal code.