Anonymous Human
Anonymous Human

Reputation: 1948

Grails many to many relationship concern

I have an application where Owner objects can have many Account objects and Account objects can have many Owner objects. I thought of modelling this with a many to many relationship but then I realized that I may also need to create Account objects where the Owner cannot be immediately determined or may be created in the future AFTER the account has already been created. Therefore I do not believe I can use the Grails many to many relationship(I think). So, I was just going to have a property in the Owner class that was a list of Account ids(this would be the Owner's Accounts references) and a property in the Account class which is a list of Owner ids(this would be the Account's Owners references). Any better ideas? I feel this is too old fashioned and is akin to the C++ pointers way of doing it.

Upvotes: 0

Views: 81

Answers (2)

injecteer
injecteer

Reputation: 20717

Frankly, I have used m2m relation only once in my 6+ years "Grails-career". Instead a combination of o2m and dynamic queries is easier to implement and maintain and usually more performant.

Upvotes: 1

maamirtalib
maamirtalib

Reputation: 455

You can create a third domain to resolve the relation like this

class Owner{
    ...

    Set<Object> getObjects() {
        OwnerObject.findAllByOwner(this).collect { it.object } as Set // or replace with optimized criteria
    }
    ...
}

class Object{
    ...

    Set<Owner> getOwners() {
        OwnerObject.findAllByObject(this).collect { it.owner } as Set // or replace with optimized criteria
    }
    ...
}


class OwnerObject implements Serializable {

    Owner owner
    Object object

    boolean equals(other) {
        if (!(other instanceof OwnerObject)) {
            return false
        }
        other.owner?.id == owner?.id && other.object?.id == object?.id
    }

    static OwnerObject get(long ownerId, long objectId) {
        find 'from OwnerObject where owner.id=:ownerId and object.id=:objectId',
                [ownerId: ownerId, objectId: objectId]
    }

    static OwnerObject create(Owner owner, Object object, boolean flush = false) {
        new OwnerObject(owner: owner, object: object).save(flush: flush, insert: true)
    }

    static boolean remove(Owner owner, Object object, boolean flush = false) {
        OwnerObject instance = OwnerObject.findByOwnerAndObject(owner, object)
        if (!instance) {
            return false
        }
        instance.delete(flush: flush)
        true
    }

    static void removeAll(Owner owner) {
        executeUpdate 'DELETE FROM OwnerObject WHERE owner=:owner', [owner: owner]
    }

    static void removeAll(Object Object) {
        executeUpdate 'DELETE FROM OwnerObject WHERE object=:object', [object: object]
    }

    static mapping = {
        id composite: ['object', 'owner']
        version false
    }
}

Upvotes: 1

Related Questions