繁体   English   中英

等于grails中的域类

[英]Equals for domain class in grails

以下等于代码的域返回错误结果

boolean equals(o) {
  if (o == null) return false
  if (this.is(o)) return true
  getClass() == o.class && id == o.id
}

对于两个具有相同ID的已加载实体,返回false。 Id等于(DB中的一条记录)。 但是班级不一样。

实体-另一个域中的字段。 看起来GORM使用了一些包装器类。

如何避免这种问题?

如您所见,要求类相同是非常严格的。 使用instanceof通常更安全,例如

class Foo {
    boolean equals(o) {
        if (!o) return false
        if (is(o)) return true
        o instanceof Foo && id == o.id
    }
}

equalshashCode使用id通常在域类中是个坏主意,因为您无法比较持久类和非持久类。 例如

class Foo {
    String name
    boolean equals(o) {
        if (!o) return false
        if (is(o)) return true
        o instanceof Foo && id == o.id
    }
}

使用此类,这将失败:

new Foo(name: 'foo').save()
assert Foo.findByName('foo') == new Foo(name: 'foo')

但是在这两种情况下,所有重要的类数据(在这种情况下只是name属性)都是相同的。

更糟糕的是,假设您创建的hashCode方法也被破坏,如果您将一个非持久实例添加到基于哈希的集合(例如HashSet )中,然后将其保存,其id将从null更改为某个long值,因此它将哈希码值。 这将导致实例在集合中变得“丢失”。

GormInstanceApi中的特殊方法在哪里

/**
 * Proxy aware instanceOf implementation.
 */
boolean instanceOf(D o, Class cls) {
    if (o instanceof EntityProxy) {
        o = (D)((EntityProxy)o).getTarget()
    }
    return o in cls
}

使用这种方法解决了问题

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM