Search code examples
hibernategrailsgrails-ormcriteriahibernate-criteria

How do I use 'in' in criteria to query sub-objects?


I want to query all objects that have child objects within a given list.

class Parent {
    Child child

    static namedQueries = {
        getParentsByListOfChildren { childList ->
            'in'('child', childList.collect {it.id})
        }
    }
}

class Child {
}

def listOfChildren = [child1, child2]  // child1 and child2 are instances of Child
def results = Parent.getParentsByListOfChildren(listOfChildren)

I'm getting the following exception in an integration test:

property.BasicPropertyAccessor HHH000122: IllegalArgumentException in class: com.me.Parent, getter method of property: id
| Failure:  getParentsByListOfChildren correctly filters trains (com.me.ParentIntegrationSpec)
|  org.hibernate.PropertyAccessException: IllegalArgumentException occurred calling getter of com.me.parent.id
    at org.grails.datastore.gorm.GormStaticApi.withCriteria_closure11(GormStaticApi.groovy:304)
    at org.grails.datastore.mapping.core.DatastoreUtils.execute(DatastoreUtils.java:302)
    at org.grails.datastore.gorm.AbstractDatastoreApi.execute(AbstractDatastoreApi.groovy:37)
    at org.grails.datastore.gorm.GormStaticApi.withCriteria(GormStaticApi.groovy:303)

How do I use in within a criteria where the objects are not simple objects? I'm assuming I need to use the id of the Child?


Solution

  • There are two other ways you can write criteria query except one suggested by @dmahapatro. I'm pointing them here for reference.

    Solution 1: Suggested by @dmahapatro

    getParentsByListOfChildren { childList ->
        'in'('child.id', childList*.id )
    }
    

    Solution 2:

    getParentsByListOfChildren { childList ->
        createAlias("child", "childFoo")   // Name is just an example, you can use anything in second parameter
        'in'('childFoo.id', childList*.id)
    }
    

    Solution 3:

    getParentsByListOfChildren { childList ->
        child {
            'in'('id', childList*.id)
        }
    }
    

    All are similar, just writing style is different according to convenience.