6.2.1.2 One-to-many 2.3.8

See the light - agile, industrial strength, rapid web application development made easy

(Quick Reference) # 6.2.1.2 One-to-many - Reference Documentation Authors: Graeme Rocher, Peter Ledbrook, Marc Palmer, Jeff Brown, Luke Daley, Burt Beckwith, Lari Hotari Version: 2.3.8 ## 6.2.1.2 One-to-many A one-to-many relationship is when one class, example `Author`, has many instances of 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)for (book in a.books) {
        println book.title
    }
The default fetch strategy used by Grails is "lazy", which means that the collection will be lazily initialized on first access. 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
    }
| Quick Reference (hide)