Grails 3 @Delegate 表示法,使用域对象
Posted
技术标签:
【中文标题】Grails 3 @Delegate 表示法,使用域对象【英文标题】:Grails 3 @Delegate notation, using a domain object 【发布时间】:2016-04-10 20:32:40 【问题描述】:在 Grails 2.4.4 中,我们将类用作域对象的包装器。
它们看起来像这样:
class Foo
@Delegate
OurDomainClass ourDomainClass
...
这行得通,但是当尝试在 Grails 3.0.11 下编译时,我们得到了这个:
> Foo.groovy: 14: Can't have an abstract method in a non-abstract class.
> The class 'Foo' must be declared abstract or the method
> 'org.springframework.validation.Errors
> org_grails_datastore_gorm_GormValidateable__errors$get()' must be
> implemented. @ line 14, column 1. class Foo ^
删除@Delegate
注释将使编译通过,但对底层类的方法的调用显然不起作用。
有没有办法解决这个问题或实现相同的行为并让它在 Grails 3 下通过编译?
【问题讨论】:
您是否尝试将@Validatable
添加到您的包装器中?
在 grails 3.x 命令实现接口 Validatable 而不是 @Validatable...
请原谅我的无知,但是用类包装域背后的想法是什么?是否将 DAO 层与视图层解耦,这样视图对数据库结构的了解为零?如果是这样,您的服务层是否总是返回 Wrapper 对象?你的插入和更新呢?您的 Service 层是否始终接收 Wrapper 对象?
@Viriato - 这样域类本身就不会被一堆方法弄得杂乱无章 - 它本质上被用作装饰器。
【参考方案1】:
老static hasMany = []
或static hasOne = []
不会做这项工作吗?当然,包装器也可以是领域类。
【讨论】:
【参考方案2】:您可以通过更改包装类来实现 GORM 特征来解决此问题:
class Foo implements GormValidateable, DirtyCheckable, Validateable
@Delegate
OurDomainClass ourDomainClass
...
我更进一步,创建了自己的界面:
class Foo implements GormDelegateHack
@Delegate
OurDomainClass ourDomainClass
...
interface GormDelegateHack extends GormValidateable, DirtyCheckable, Validateable
我针对 grails-data-mapping 提交了 issue #856,尽管它可能是 Groovy bug。
【讨论】:
【参考方案3】:@timbonicus 的解决方案适用于 Grails 3,但在 Grails 4 上失败并出现多个错误。
最终将 @Delegate
类更改为 Groovy traits 作为替代方案。它仍然是分开的,因为特征支持多重继承和实现的方法。此外,不需要像 embedded
、hasMany
和 hasOne
那样向对象添加另一个调用。
trait OurDomainClass
trait OurOtherDomainClass
class Foo implements OurDomainClass, OurOtherDomainClass
如果你正在创建插件,你可以add methods at compile time with traits。
【讨论】:
以上是关于Grails 3 @Delegate 表示法,使用域对象的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Grails 3 中使用外部 .groovy 配置文件