简体   繁体   中英

Grails Domain Object hasMany irregular behaviour using contains

I'm having an issue where calling .contains() on one of my domain classes' hasMany relationships is not doing the same when running normally, or when debugging. The situation is as follows:

I have 2 domain objects, A and B . A has a hasMany relationship with B .

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

Now, during the execution of one of my filters, I grab my current user from the spring security service. This user also contains a single instance of B . What my filter should do is to check if the instance of B in the user is contained in some instance of A .

Assume that the instances of B are actually referring to the same object (since they are).

Now, the issue arises. Calling:

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

prints failure during normal (or debugging without stepping through the code) execution. However, if I put a break-point there, and step through the code, it correctly executes the contains() and prints success .

I have also implemented equals , hashCode and compareTo in an attempt to resolve this, but with the same behaviour.

This is usually due to lazyloading or cache. Use instanceOfA.bees.id.contains(user.instanceOfB.id) and it always works.

Maybe your user.instanceOfB object is a hibernate proxy object and therefore not a real B. You can check this using a debugger or printing user.instanceOfB.getClass() .

You can use GrailsHibernateUtil.unwrapIfProxy(proxyObject) to get the real object from the proxy.

我会用HQL做到这一点:

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

So it seems that using one of the Groovy transform annotations seems to do the trick. Simply adding:

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

does the trick. Seems a bit strange that the IDE generated methods (using the same fields) did not...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM