我想使用grails 1.3.7交叉两个特定域类的实例列表。
问题是,一个列表的实例是由javasisst创建的,因此交集的结果总是一个空列表。
以下是我的域名:
class User {
...
static hasMany = [foos : Foo]
...
}
class Foo {
...
static hasMany = [bars : Bar]
...
}
class Bar {
...
static hasMany = [localizedTitles : LocalizedTitle]
...
}
我得到用户的所有Bar
个实例的列表,如下所示:
def allBarsOfUser = userInstance.foos.bars.flatten()
尝试与另一个Bar
个实例列表相交:
def intersectedBars = bars.intersect(allBarsOfUser)
问题是,allBarsOfUser
ist Bar_$$_javassist_139
的元素类型和bars
的元素类型是Bar
,因此intersectedBars
总是[]
。
我通过以下方式解决了我的问题 - 但我不喜欢这个解决方案:
def allBarsOfUser = userInstance.foos.bars.flatten().collect{Bar.get(it.id)}
什么是更好的解决方案?
我如何将Bar_$$_javassist_139
投射到Bar
以便intersect()
正常工作?
答案 0 :(得分:1)
这取决于你实际上要做什么。 intersect
方法最终依赖于equals
,因此,如果您在equals
中实施hashCode
和Bar
,那么它将会执行您想要的操作。但是您通常不应该在对象ID方面实现equals
,因为ID仅在保存对象时分配,因此您无法将新创建的对象与先前保存的对象进行比较。 Hibernate建议你implement it based on a business key(不是生成的ID但是在整个对象的生命周期内稳定且不太可能改变的东西)
class UserAccount {
String username
String realname
public boolean equals(that) {
return ((that instanceof UserAccount)
&& (this.username == that.username))
}
public int hashCode() {
username.hashCode()
}
}
因此,如果您确实需要ID比较,那么明确地做到这一点就更清楚了。
def userBarIds = allBarsOfUser*.id
def intersectedBars = bars.findAll { it.id in userBarIds }