以下等于代码返回域
的错误结果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使用了一些包装类。
如何避免这种问题?
答案 0 :(得分:0)
正如您所看到的,要求课程相同是非常严格的。使用instanceof
通常更安全,例如
class Foo {
boolean equals(o) {
if (!o) return false
if (is(o)) return true
o instanceof Foo && id == o.id
}
}
在id
或equals
中使用hashCode
在域类中通常是一个坏主意,因为您无法比较持久类和非持久类。例如
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
)然后保存它,它的{{ 1}}将从null更改为某个long值,因此其hashcode值也将更改。这将导致实例在集合中“丢失”。
答案 1 :(得分:0)
GormInstanceApi中的特殊方法在哪里
/**
* Proxy aware instanceOf implementation.
*/
boolean instanceOf(D o, Class cls) {
if (o instanceof EntityProxy) {
o = (D)((EntityProxy)o).getTarget()
}
return o in cls
}
使用此方法解决了问题