[英]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. 在equals
或hashCode
使用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.