使用@DomainEquals生成领域类的equals方法?
李小翔
2014-05-17 14:08

内容列表

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 实现：
· 	比较除 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”]
· 	   } 
· 	} 
· 	比较 Domain 实例和 Map 对象，如下例所示，如果Domain实例的 name 属性和一个Map对象中的同名键值相同，则认为两个对象相等：
· 	@DomainEquals(compareMap = true, includes = ”name”)
·