继承的grails域类缺少动态属性

时间:2014-05-30 23:17:31

标签: grails gorm

我遇到一个问题,在使用继承时,相关的表id字段从我的域对象返回'null'。这是一个例子:

在/ src / groovy /

BaseClass1.groovy

class BaseClass1 {
    Long id
    static mapping = {
        tablePerConcreteClass true
    }
}

BaseClass2.groovy

class BaseClass2 extends BaseClass1 {
    String someOtherProperty
    static constraints = {
        someOtherProperty(maxSize:200)
    }
    static mapping = BaseClass1.mapping
}

在/ grails-app / domain

ParentClass.groovy

class ParentClass extends BaseClass2 {
    ChildClass myChild

    static mapping = BaseClass2.mapping << {
        version false
    }
}

ChildClass.groovy

class ChildClass extends BaseClass1 {
    String property

    static mapping = BaseClass1.mapping
}

问题出现在这里:

SomeotherCode.groovy

print parentClassInstance.myChild.id // returns the value
print parentClassInstance.myChildId // returns null

任何想法可能会让这些动态属性像这样破坏?

2 个答案:

答案 0 :(得分:4)

调试到get(AssociationName)Id源后,我发现以下内容: 处理程序是:

GrailsDomainConfigurationUtil.getAssociationIdentifier(Object target, String propertyName,
        GrailsDomainClass referencedDomainClass) {

    String getterName = GrailsClassUtils.getGetterName(propertyName);

    try {
        Method m = target.getClass().getMethod(getterName, EMPTY_CLASS_ARRAY);
        Object value = m.invoke(target);
        if (value != null && referencedDomainClass != null) {
            String identifierGetter = GrailsClassUtils.getGetterName(referencedDomainClass.getIdentifier().getName());
            m = value.getClass().getDeclaredMethod(identifierGetter, EMPTY_CLASS_ARRAY);
            return (Serializable)m.invoke(value);
        }
    }
    catch (NoSuchMethodException e) {
        // ignore
    }
    catch (IllegalAccessException e) {
        // ignore
    }
    catch (InvocationTargetException e) {
        // ignore
    }
    return null;
}

它在相关类(value.getClass()。getDeclaredMethod)上抛出异常,为方法getId()说NoSuchMethod。如果没有Grails抱怨需要标识符列,我无法从基类中删除id声明。我尝试将id标记为公开,并且还抱怨它不在那里。所以,我试过这个

BaseClass {
    Long id
    public Long getId() { return this.@id }
}

并且某些课程的内容有效,但其他课程则不然。

当我删除I​​D声明时,我发出错误:“找不到Identity属性,但在域类中需要”。一时兴起,我尝试将@Entity添加到具体类和中提琴中!一切都开始了。

class BaseClass {
    //Don't declare id!
}

@Entity
class ParentClass {}

@Entity
class ChildClass {}

我仍然认为这是一个需要添加的grails bug,但至少它很容易解决。

答案 1 :(得分:0)

我不确定你为什么会看到这种行为,但我也不确定你为什么要做一些你在这里做的事情。为什么域类扩展了POGO?域,控制器和服务由Grails机器严格管理,这可能不是为这种用途而设计的。具体来说,我相信Grails为GrailsDomainClass(而非POGO)的GrailsDomainProperty构建动态属性getter。在这种情况下,您在BaseClass1中有一个显式声明的id字段,它不是GrailsDomainProperty。我怀疑这个POGO id属性不被Grails机器拾取,它为域创建了动态属性getters。

您可以尝试将BaseClass1 / 2放在/ grails-app / domain中,如果您不希望它们被实例化,可能会将它们抽象化,然后按原样扩展它们,看看您是否观察到了您想要的行为。