如果我创建一个这样的抽象域类:
abstract class DomainBase {
LocalDateTime created = LocalDateTime.now()
LocalDateTime updated
static constraints = {
created nullable: false
updated nullable: true
}
static mapping = {
tablePerConcreteClass true
created column: 'CREATED'
updated column: 'UPDATED'
}
def beforeUpdate() {
this.updated = LocalDateTime.now()
}
}
然后我可以使用它扩展其他域类,它们将继承所有内容(属性,约束,映射和拦截器),并且生成的数据库不包含具体的DOMAIN_BASE
表。一切都按预期工作。
但是,如果我创建另一个扩展DomainBase的抽象类,例如:
abstract class EntityBase extends DomainBase {
User createdBy
Boolean active = true
static constraints = {
createdBy nullable: false
active nullable: true
}
static mapping = {
tablePerConcreteClass true
createdBy column: 'CREATED_BY_ID'
active column: 'ACTIVE'
}
}
然后生成的数据库将具有一个具体的ENTITY_BASE
表。这就是问题所在。
我可以收集的建议解决方案是让基类是普通的POGO而不是域对象,但是映射不是继承的,而且我很懒,不能将映射粘贴到我创建的每个域类。
此外,如果我尝试使这些域对象成为特征,我甚至无法运行应用程序,因为它在编译期间会破坏NPE。
有没有简单而优雅的方法来解决这个问题?
答案 0 :(得分:1)
据我所知,你不能继承Grails 2.4.x中的映射,它认为这在2.5.0中是相同的......
作为一种解决方法,您可以使用和更改域类的脚手架模板。
答案 1 :(得分:0)
我目前对此感到满意的解决方案是This SO answer的改编仅包含在“Utility”闭包中,看起来像这样:
/**
* Domain related utilities
*/
class DomainUtil {
private DomainUtil() {}
/**
* Utility for inheriting mapping definitions from non-domain classes (classes defined in src/groovy)<br/>
* Adapted from <a href="https://stackoverflow.com/a/18339655/1182835">https://stackoverflow.com/a/18339655/1182835</a>
* @param source - source class from which to inherit the mappings
* @param destination - closure to which the mappings will be added
*/
static def inheritDomainMappingFrom = { source, destination ->
def copyMapping = source.mapping.clone()
copyMapping.delegate = destination
copyMapping.call()
}
}
它的用法如下:
给定一些抽象类Foo
,它具有映射闭包并存储在src/groovy
内,因此它不被视为域类:
abstract class Foo {
LocalDate prop1
Boolean prop2
static mapping = {
prop1 column: "PROP1_DATE", type: PersistentLocalDate
prop2 column: "IS_PROP2"
}
}
继承Bar
的域类Foo
:
class Bar extends Foo {
Integer prop3
String prop4
String prop5
static mapping = {
DomainUtil.inheritDomainMappingFrom(Foo, delegate)
prop3 column: 'PROP3'
prop4 column: 'PROP4'
prop5 column: 'PROP5'
}
}
使用DomainUtil.inheritDomainMappingFrom(Foo, delegate)
我的Bar
域类将继承Foo
抽象基类的所有映射定义。对我来说,这是一个充分的妥协,因为它更容易编写,也可以让加入或维护项目的人理解。
Extending Scaffolding Templates也是一种可行的解决方案,但它包含一些让我失望的缺点:
但是,对于我的所有域类添加@ToString
注释的内容非常有用。