如何将javassist实例转换为特定域的实例

时间:2012-07-26 09:33:50

标签: grails gorm

我想使用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()正常工作?

1 个答案:

答案 0 :(得分:1)

这取决于你实际上要做什么。 intersect方法最终依赖于equals,因此,如果您在equals中实施hashCodeBar,那么它将会执行您想要的操作。但是您通常不应该在对象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 }