A one-to-many relationship is when one class, example Author, has many instances of a another class, example Book. With Grails you define such a relationship with the hasMany setting:

class Author {
    static hasMany = [ books : Book ]

String name } class Book { String title }

In this case we have a unidirectional one-to-many. Grails will, by default, map this kind of relationship with a join table.

The ORM DSL allows mapping unidirectional relationships using a foreign key association instead

Grails will automatically inject a property of type java.util.Set into the domain class based on the hasMany setting. This can be used to iterate over the collection:

def a = Author.get(1)

a.books.each { println it.title }

The default fetch strategy used by Grails is "lazy", which means that the collection will be lazily initialized. This can lead to the n+1 problem if you are not careful.

If you need "eager" fetching you can use the ORM DSL or specify eager fetching as part of a query

The default cascading behaviour is to cascade saves and updates, but not deletes unless a belongsTo is also specified:

class Author {
    static hasMany = [ books : Book ]

String name } class Book { static belongsTo = [author:Author] String title }

If you have two properties of the same type on the many side of a one-to-many you have to use mappedBy to specify which the collection is mapped:

class Airport {
	static hasMany = [flights:Flight]
	static mappedBy = [flights:"departureAirport"]
}
class Flight {
	Airport departureAirport
	Airport destinationAirport
}

This is also true if you have multiple collections that map to different properties on the many side:

class Airport {
	static hasMany = [outboundFlights:Flight, inboundFlights:Flight]
	static mappedBy = [outboundFlights:"departureAirport", inboundFlights:"destinationAirport"]
}
class Flight {
	Airport departureAirport
	Airport destinationAirport
}