Search code examples
grailsgrails-orm

Grails GORM: How do I create a composite primary key and use it for a table relationship?


I have two tables, one of which (legacy table: A) has two fields that should serve as a composite foreign key and the other one (new table: B) should use a composite primary key for a each row:A has one row:B relationship. How do I describe these tables in terms of GORM?

So far I've been able to create a domain class that reflects the legacy table:A

class A {

    ...
    //composite foreign key to link B class
    String className;
    String eventName;

    B b; //instance of B to be related

    static mapping = {
        table 'a_table';            
        id column: 'id';
        className column: 'class_name';
        eventName column: 'event_name';
        //b: ???
    }
}

which works, but I can't create a new class:B and the relationship.

I tried to declare B as:

class B implements Serializable{

    static auditable = true;

    String name;
    String className;
    String eventName;

    static mapping = {
        //supposed to make a composite PK
        id composite:[className, eventName] 
    }
}

but this won't compile with a
ERROR context.GrailsContextLoader - Error executing bootstraps: Error evaluating ORM mappings block for domain [com.package.B]: No such property: eventName for class: org.codehaus.groovy.grails.orm.hibernate.cfg.HibernateMappingBuilder

What I want is something like:

static mapping = {
    ...
    b composite: [b.className:className, b.eventName:eventName]
    //or whatever is the right way for this to be done.
}

for the A class to make GORM handle this relation.


Solution

  • Did you try to use attribute name instead of use attribute value ?

    class B implements Serializable{
        String name;
        String className;
        String eventName;
    
        static mapping = {
            //supposed to make a composite PK
            id composite:['className', 'eventName'] 
        }
    }
    

    And mapping in A :

    class A {
        static hasMany = [ b : B ]
    }
    

    No need to have className or eventName in A