How does one setup cascading save, update, and delete operations for Multiple Domain Classes that are each composed of a Single Shared Domain Class?

StackOverflow https://stackoverflow.com/questions/18539474

Question

Given the following Domain Classes:

The shared entity (C) can't use belongsTo to set up cascading for both A and B since an instance will only ever belong to one or the other.

What is the best way to model this with Gorm?

class EntityA {
    static hasOne = [enitityC: SharedEntityC]
}

class EntityB {
    static hasOne = [enitityC: SharedEntityC]
}

class SharedEntityC {
   String foo
   // Can't use belongsTo to set up cascading
}

I've looked to the following:

http://grails.org/doc/2.0.x/guide/single.html#cascades
http://grails.org/doc/2.0.x/guide/single.html#customCascadeBehaviour


I've tried the Strategy Pattern:

interface Shareable {
    Shared sharedEntity
}
class EntityA implements Shareable {
    static hasOne = [sharedEntity: Shared]
}
abstract class Shared {
    static belongsTo = [shareable: Shareable]
}
class SharedEntityC extends Shared {
   String foo
}

But this is un-groovy according to some, and Gorm seems to only care about concrete classes.


I've tried interceptors:

class EntityA {
    SharedEntityC enitityC

    def afterDelete {
        this.entityC.delete() // Results in readonly session error
    }
}

class EntityA {
    SharedEntityC enitityC

    def beforeDelete {
        this.entityC.delete() // Results in fk constraint violation
    }
}

Another option would be:

class EntityASharedEntityC {
    EntityA entityA
    SharedEntityC entityC
    ...
    // a bunch of static methods for managing the relationship
    ...
}
class EntityBSharedEntityC {
    EntityB entityB
    SharedEntityC entityC
    ...
    // a bunch of static methods for managing the relationship
    ...
}

...
// Plus a new class for each entity containing SharedEntityC.
...

But this seems like a long way around defining a straightforward composite relationship.


Before the answer:

class EntityA {
    SharedEntityC enitityC

    def afterDelete() {
        this.deleteSharedEntityC()
    }

    void deleteSharedEntityC() {
        if(this.sharedEntityC) {
            this.sharedEntityC.beforeDelete() // It has some cleanup to do itself
            SharedEntityC.executeUpdate('delete SharedEntityC where id=:id', 
                          [id: this.sharedEntityC.id]) // Go around Gorm
        }
    }
}

Even though I arrived at a solution I can live with, I wonder if these classes can be modeled in a way that wouldn't require me to bend Gorm in this way.

Any suggestions are welcome and appreciated... :-)


After the answer:

class EntityA {
    SharedEntityC entityC

    static mapping = {
        entityC cascade: 'all'
    }
}

class EntityB {
    SharedEntityC entityC

    static mapping = {
        entityC cascade: 'all'
    }
}

class SharedEntityC {
   String foo
   // Leave out belongsTo
}

Much, much better...

Was it helpful?

Solution

On the entity classes did you try specifying the cascade:

static mapping = {
  enitityC cascade: 'all'
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top