7.3.3 Understanding Cascading Updates and Deletes 3.1.4

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

(Quick Reference) # 7.3.3 Understanding Cascading Updates and Deletes - Reference Documentation Authors: Graeme Rocher, Peter Ledbrook, Marc Palmer, Jeff Brown, Luke Daley, Burt Beckwith, Lari Hotari Version: 3.1.4 ## 7.3.3 Understanding Cascading Updates and Deletes It is critical that you understand how cascading updates and deletes work when using GORM. The key part to remember is the `belongsTo` setting which controls which class "owns" a relationship. Whether it is a one-to-one, one-to-many or many-to-many, defining `belongsTo` will result in updates cascading from the owning class to its dependant (the other side of the relationship), and for many-/one-to-one and one-to-many relationships deletes will also cascade. If you do not define `belongsTo` then no cascades will happen and you will have to manually save each object (except in the case of the one-to-many, in which case saves will cascade automatically if a new instance is in a `hasMany` collection). Here is an example:
    class Airport {
        String name
        static hasMany = [flights: Flight]
    }
    class Flight {
        String number
        static belongsTo = [airport: Airport]
    }
If I now create an `Airport` and add some `Flight`s to it I can save the `Airport` and have the updates cascaded down to each flight, hence saving the whole object graph:
    new Airport(name: "Gatwick")
            .addToFlights(new Flight(number: "BA3430"))
            .addToFlights(new Flight(number: "EZ0938"))
            .save()
Conversely if I later delete the `Airport` all `Flight`s associated with it will also be deleted:
    def airport = Airport.findByName("Gatwick")
    airport.delete()
However, if I were to remove `belongsTo` then the above cascading deletion code would not work. To understand this better take a look at the summaries below that describe the default behaviour of GORM with regards to specific associations. Also read part 2 of the GORM Gotchas series of articles to get a deeper understanding of relationships and cascading. ##### Bidirectional one-to-many with belongsTo
    class A { static hasMany = [bees: B] }
    class B { static belongsTo = [a: A] }
In the case of a bidirectional one-to-many where the many side defines a `belongsTo` then the cascade strategy is set to "ALL" for the one side and "NONE" for the many side. ##### Unidirectional one-to-many
    class A { static hasMany = [bees: B] }
    class B {  }
In the case of a unidirectional one-to-many where the many side defines no belongsTo then the cascade strategy is set to "SAVE-UPDATE". ##### Bidirectional one-to-many, no belongsTo
    class A { static hasMany = [bees: B] }
    class B { A a }
In the case of a bidirectional one-to-many where the many side does not define a `belongsTo` then the cascade strategy is set to "SAVE-UPDATE" for the one side and "NONE" for the many side. ##### Unidirectional one-to-one with belongsTo
    class A {  }
    class B { static belongsTo = [a: A] }
In the case of a unidirectional one-to-one association that defines a `belongsTo` then the cascade strategy is set to "ALL" for the owning side of the relationship (A->B) and "NONE" from the side that defines the `belongsTo` (B->A) Note that if you need further control over cascading behaviour, you can use the ORM DSL. | Quick Reference (hide)