我遇到一个问题,在使用继承时,相关的表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
任何想法可能会让这些动态属性像这样破坏?
答案 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 }
}
并且某些课程的内容有效,但其他课程则不然。
当我删除ID声明时,我发出错误:“找不到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中,如果您不希望它们被实例化,可能会将它们抽象化,然后按原样扩展它们,看看您是否观察到了您想要的行为。