在Grails中使用抽象(或非抽象)继承时,以下内容对我不起作用。
很快,我的继承如下:
abstract BaseClass { ... }
SomeClass extends BaseClass { ... }
SomeOtherClass extends BaseClass { ... }
然后在另一个域对象中:
ThirdClass {
...
BaseClass baseProperty
...
}
但是现在,当我尝试将该属性设置为SomeClass
或SomeOtherClass
实例时,Grails会重复:
错误util.JDBCExceptionReporter - 无法添加或更新子行:外键约束失败 ...
这不可能吗?
我也试过让基类不是抽象的,并且还尝试将SomeClass
或SomeOtherClass
个实例转换为BaseClass
。它们会产生相同的错误。
更新
我刚刚检查过。它适用于我添加的第一个子类。但是一旦我尝试添加其他子类就失败了。
换句话说:
def prop1 = new ThirdClass(baseProperty: instanceOfSomeClass).save()
工作正常。但是当我尝试做的时候:
def prop2 = new ThridClass(baseProperty: instanceOfSomeOtherClass).save()
失败了。
更新2
进一步调查表明,在表创建过程中出现了问题。它正确地向ThirdClass
表添加了两个外键,但键错误地引用了:
CONSTRAINT `...` FOREIGN KEY (`some_id`) REFERENCES `base_class` (`id`),
CONSTRAINT `...` FOREIGN KEY (`some_id`) REFERENCES `some_class` (`id`)
不知道为什么选择基类和其中一个子类?我试过清洁等。
答案 0 :(得分:7)
首先,创建您的BaseClass 外部域结构。它必须是一个外部类,把它放在脚本文件夹,源文件夹中。
package com.example.model
/**
* @author Inocencio
*/
class BaseClass {
Date createdAt = new Date()
}
现在,创建一个常规域类并对其进行扩展。
package com.example.domain
import com.example.model.BaseClass
class SomeClass extends BaseClass {
String name
static constraints = {
name(nullable: false)
}
}
正如您所看到的,一旦您持久化SomeClass,一个createdAt字段也会被填充并保存。检查测试类:
@TestFor(SomeClass)
class SomeClassTests {
void testSomething() {
def some = new SomeClass()
some.name = "Hello There"
some.save()
//find it
def someFind = SomeClass.list()[0]
assert someFind
assertTrue someFind.createdAt != null
// println "Date: $someFind.createdAt"
// println "Name: $someFind.name"
}
}
我希望它有所帮助。
答案 1 :(得分:0)
我刚刚创建了类结构(Grails 2.1.0)并且没有问题。它在模拟和单元测试时有效。当scaffolded和SomeClass和ThirdClass实例从表单中保存时也是如此。 尝试清理您的数据库,特别是如果您没有使用'create-drop'模式。也许还有一些旧约束。 最后,您没有指定何时发生错误 - 保存(创建或更新)?在属性集上获取JDBC异常是不太可能的,是吗? 我不记得肯定但是默认情况下可能没有级联简单属性,然后在保存ThirdClass实例之前尝试保存SomeClass实例。您也可以通过使用hasOne关系来自动级联而不是声明简单属性,如:
class ThirdClass {
...
static hasOne = [baseProperty:BaseClass]
}