Grails/Gorm: Inheritance and foreign keys

Given Domain Classes like these:

class A {   // in reality this is a basic User class that is required in multiple projects
}

class B extends A { // in reality B is a "patient"-kind of user. 
    static hasMany = [c: C]
}

// c/d is stuff like "MedicationPrescription", so basically data only relevant to the patient. However the system needs to realize that Patients are Users, as the User base class is used for spring security logins and in general has a lot of the basic data a person just has. (Name, etc.)
class C {
    static belongsTo = [b: B, a: A, d: D]
}

class D {
}

I get this error:

org.hibernate.MappingException: Foreign key (FK_pwu2w72ul5a5213husrv3onr3:c [])) must have same number of columns as the referenced primary key (a [id])
        at org.hibernate.mapping.ForeignKey.alignColumns(ForeignKey.java:110)
        at org.hibernate.mapping.ForeignKey.alignColumns(ForeignKey.java:93)
        at org.hibernate.cfg.Configuration.secondPassCompileForeignKeys(Configuration.java:1818)
        at org.hibernate.cfg.Configuration.originalSecondPassCompile(Configuration.java:1741)
        at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1426)
        at org.grails.orm.hibernate.cfg.HibernateMappingContextConfiguration.secondPassCompile(HibernateMappingContextConfiguration.java:287)
        at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1846)
        at org.grails.orm.hibernate.cfg.HibernateMappingContextConfiguration.buildSessionFactory(HibernateMappingContextConfiguration.java:196)
        at org.grails.orm.hibernate.HibernateMappingContextSessionFactoryBean.doBuildSessionFactory(HibernateMappingContextSessionFactoryBean.java:476)
        at org.grails.orm.hibernate.HibernateMappingContextSessionFactoryBean.buildSessionFactory(HibernateMappingContextSessionFactoryBean.java:470)
        at org.grails.orm.hibernate.HibernateMappingContextSessionFactoryBean.afterPropertiesSet(HibernateMappingContextSessionFactoryBean.java:93)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1637)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1574)
        ... 41 common frames omitted

The error goes away if I remove the inheritance between A and B, but I havee this constellation in my Domain. I don't understand why Gorm does what it does, from the error message it seems to think the list of attributes in the foreign key is empty?

Additionally I cannot even mention classes B, C or D in class A, as class A is part of a plugin that just doesn't know about those classes.

EDIT: I might just do away with the inheritance and use composition instead like this:

class B {
  A a
  static hasMany = [c: C]
}

That doesn't blow up on startup at least, but still: Why?

Answers


You can take care of your domain class constellation like this:

class User { }

class Patient extends User {
    static hasMany = [prescriptions: MedicationPrescription, stuff: OtherStuff]
}

class MedicationPrescription {
    static belongsTo = [patient: Patient]
}

class OtherStuff {
    static belongsTo = [patient: Patient]
}

This creates a bi-directional one-to-many association between Patient and MedicationPrescription and also between Patient and OtherStuff. Notice that each belongsTo has a corresponding hasMany.

As you've already discovered, you can also use composition.


Need Your Help

ActionScript Continuously Dragging Objects Within Bounds From Off-Stage Mouse Coordinates?

flash actionscript-3 drag-and-drop mouseevent stage

is it possible for flash to detect off-stage mouse coordinates in order to continuously drag an object within its bounds while the mouse is moving outside of the stage?

Unable to get Struts2-jquery-grid Row Id for deleting

java jquery struts2 jqgrid

I am developing a small application in struts 2 with Jquery Grid for displaying data results.