Grails Domain Object使用contains有很多不规则的行为

时间:2013-09-03 16:20:22

标签: grails groovy gorm

我遇到一个问题,在我的某个域类.contains()关系上调用hasMany在正常运行或调试时没有做同样的事情。情况如下:

我有2个域对象,ABAhasMany的关系B

class A {
    ...
    static hasMany = [bees: B]
    ...
}

现在,在执行我的一个过滤器期间,我从spring安全服务中获取当前用户。此用户还包含B的单个实例。我的过滤器应该做的是检查用户B中的实例是否包含在A的某个实例中。

假设B的实例实际上是指同一个对象(因为它们是)。

现在,问题出现了。主叫:

if (instanceOfA.bees.contains(user.instanceOfB)) {
    println 'success'
} else {
    println 'failure'
}

在正常(或不通过代码执行调试)执行期间打印failure。但是,如果我在那里放置一个断点,并逐步执行代码,它会正确执行contains()并打印success

我还实施了equalshashCodecompareTo以尝试解决此问题,但行为相同。

4 个答案:

答案 0 :(得分:3)

这通常是由于延迟加载或缓存造成的。使用instanceOfA.bees.id.contains(user.instanceOfB.id),它始终有效。

答案 1 :(得分:2)

也许您的user.instanceOfB对象是一个休眠代理对象,因此不是真实的 B.您可以使用调试器或打印user.instanceOfB.getClass()来检查它。

您可以使用GrailsHibernateUtil.unwrapIfProxy(proxyObject)从代理中获取真实对象。

答案 2 :(得分:1)

我会用HQL做到这一点:

A.executeQuery("select a from A a join a.bees as b where b = :b and a = :a", [a: instanceOfA, b: user.instanceOfB])

答案 3 :(得分:1)

所以似乎使用Groovy转换注释之一似乎可以解决问题。只需添加:

// uid is a uniqe UUID we use to identify with other systems.
@EqualsAndHashCode(includes = ["id", "uid"])

诀窍。似乎有点奇怪,IDE生成的方法(使用相同的字段)没有...