简体   繁体   English

等于grails中的域类

[英]Equals for domain class in grails

The following equals code returns wrong result for domain 以下等于代码的域返回错误结果

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

For two loaded entities with same id return false. 对于两个具有相同ID的已加载实体,返回false。 Id are equals (one record in DB). Id等于(DB中的一条记录)。 But classes not same. 但是班级不一样。

The entities -- fields in another domains. 实体-另一个域中的字段。 And it looks like GORM used some wrapper classes. 看起来GORM使用了一些包装器类。

How to avoid this kind of problem? 如何避免这种问题?

As you are seeing, requiring that the classes be the same is overly strict. 如您所见,要求类相同是非常严格的。 Using instanceof is usually safer, eg 使用instanceof通常更安全,例如

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

Using id in equals or hashCode is generally a bad idea in domain classes since you can't compare persistent and non-persistent classes. equalshashCode使用id通常在域类中是个坏主意,因为您无法比较持久类和非持久类。 For example 例如

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

With this class, this would fail: 使用此类,这将失败:

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

but all of the important class data (in this case just the name property) is identical in both cases. 但是在这两种情况下,所有重要的类数据(在这种情况下只是name属性)都是相同的。

Even worse, assuming you create a hashCode method that's similarly broken, if you add a non-persistent instance to a hash-based collection (eg HashSet ) and then save it, its id will change from null to some long value and so will its hashcode value. 更糟糕的是,假设您创建的hashCode方法也被破坏,如果您将一个非持久实例添加到基于哈希的集合(例如HashSet )中,然后将其保存,其id将从null更改为某个long值,因此它将哈希码值。 This will cause the instance to become "lost" in the collection. 这将导致实例在集合中变得“丢失”。

Where is special method in GormInstanceApi GormInstanceApi中的特殊方法在哪里

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

Using of this method solved problem 使用这种方法解决了问题

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

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