2

我想使用 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)

问题是,allBarsOfUserist的元素类型和元素的Bar_$$_javassist_139类型bars总是Bar如此。intersectedBars[]

我通过执行以下操作解决了我的问题 - 但我不喜欢该解决方案:

def allBarsOfUser = userInstance.foos.bars.flatten().collect{Bar.get(it.id)}

什么是更好的解决方案?

我怎么能Bar_$$_javassist_139这样Bar才能intersect()正常工作?

4

1 回答 1

1

这取决于你实际上想要做什么。该intersect方法最终依赖于equals,因此,如果您实施equalsand hashCodeBar那么它将执行您想要的操作。但是您通常不应该equals根据对象 ID 来实现,因为仅在保存对象时才分配 ID,因此您无法将新创建的对象与以前保存的对象进行比较。Hibernate 建议您基于业务密钥(不是生成的 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 }
于 2012-07-26T10:04:52.960 回答