-->

GORM doesn't handle mapping of associations wh

2019-06-01 12:28发布

问题:

I'm trying to map existing tables in a GORM/Grails app. Most of the tables have composite primary keys (not my choice).

I'm finding that when I map an association to a class (parent of a child) where the composite key of the parent class contains an association to a class with a composite key also (grandparent), GORM doesn't bother to check the mapping of the grandparent class and subs in a non-composite key.

Child

class Child implements Serializable {
    Parent parent
    String name

    belongsTo= [parent: Parent]

    static mapping= {
        id(composite: ['parent', 'name'])
    }
}

Parent

class Parent implements Serializable {
    GrandParent grandParent
    String name
    Collection<Child> children

    belongsTo= [grandParent: GrandParent]
    hasMany= [children: Child]

    static mapping= {
        id(composite: ['grandParent', 'name'])
    }
}

GrandParent

class GrandParent implements Serializable {
    String name
    Integer luckyNumber
    Collection<Parent> parents

    hasMany= [parents: Parent]

    static mapping= {
        id(composite: ['name', 'luckyNumber'])
    }
}

The DDL generation fails when trying to glean the foreign keys.

org.hibernate.MappingException:
Foreign key (FK_1:CHILD [parent_grandparent_id,parent_name]))
    must have same number of columns as the referenced primary key
(PARENT [parent_grandparent_name,parent_grandparent_lucky_number,parent_name])

The foreign key it's created does not match the primary key of the parent class (which it was able to decipher correctly).

回答1:

try:

Child

class Child implements Serializable {

    String name

    static belongsTo= [parent: Parent]

    static mapping= {
        id(composite: ['parent', 'name'])
    }
}

Parent

class Parent implements Serializable {
    String name

    //static belongsTo= [parent: Parent]  //why do you need this
    static belongsTo= [GrandParent  ]  //did you mean this
    static hasMany= [children: Child,grandParent: GrandParent  ]

    static mapping= {
        id(composite: ['grandParent', 'name'])
    }
}

GrandParent

class GrandParent implements Serializable {
    String name
    Integer luckyNumber

    static hasMany= [parents: Parent]

    static mapping= {
        id(composite: ['name', 'luckyNumber'])
    }
}


回答2:

I've asked around on Grails Slack #gorm, and this appears to hit a gap in Gorm mapping.

I've raised an issue in the Grails data mapping project. We'll see where this goes.