欢迎进入Wiki » FAQ » 使用@DomainEquals生成领域类的equals方法?

使用@DomainEquals生成领域类的equals方法?

在2014-05-17 14:08上被李小翔修改
评论 (0) · 附件 (0) · 记录 · 信息

Java 中,每个类会继承 java.lang.Object 的 equals 方法(可覆盖),Grails的Domain类默认也继承了该方法,一般情况下,默认的 equals 方法能满足大多数要求,但是延迟加载的情况下,一些Domain实例加载后,被包装成了一个Proxy对象(类型为 x.y.Foobar_$$_xxx),此时默认的 equals 方法就会出现问题(比如调用列表的contains、remove等方法时)。而使用 Groovy 的注解  @EqualsAndHashCode,同样无法解决该问题,反而会造成其他的异常。

bropen.toolkit.utils.grails.BeanUtils 提供了一个 equals 的API来处理这种问题,并且在编译的时候将该方法注入到了每个Domain类的class文件中。默认情况下,该API会自动处理Proxy对象的问题,并比较ID来判断两个对象是否是同一个实例。

此外,还可以手动在Domain类前使用注解 @DomainEquals 实现:

  1. 比较除 id 外的其他字段,如下例所示,只要两个同类的Domain实例的 name 属性相同(或id相同),便认为两个对象相等:
    import bropen.toolkit.transform.DomainEquals

    @DomainEquals(includes = "name")
    class Foobar {
        String name
    }

    def b1 = new Foobar( name: "abc" )
    def b2 = new Foobar( name: "abc" )
    assert b1 == b2

    以外,includes 还可以设置为逗号分隔的多个字段,如下例:
    @DomainEquals(includes = "name, age")
    这样,对于联合主键的Domain类,可以使用本注解来生成 equals 方法,如:
    @DomainEquals(includes = "user, code")
    class Foobar {
        String user
        String code

       static mapping = {
            id composite: ["user", "code"]
       }
    }
  2. 比较 Domain 实例和 Map 对象,如下例所示,如果Domain实例的 name 属性和一个Map对象中的同名键值相同,则认为两个对象相等:
    @DomainEquals(compareMap = true, includes = "name")
标签: BroToolkit
在2014-05-17 14:07上被李小翔创建

Copyright © 2013 北京博瑞开源软件有限公司
京ICP备12048974号