Search code examples
grailsgrails-ormcriteria

How to use nested attributes together with attributes from the class in a Criteria with Grails?


I have this situation:

country {
    and {
        rates{
                                and{
                                    between('effectiveDate', startDate, endDate)
                                    or {
                                        and {
                                            eq('hoursEligible', true)
                                            gt('hours', new BigDecimal(0))
                                        }
                                        and {
                                            eq('travelTimeEligible', true)
                                            gt('travel', new BigDecimal(0))
                                        }
                                        and {
                                            eq('mileageEligible', true)
                                            gt('mileage', new BigDecimal(0))
                                        }
                                        and {
                                            eq('expensesEligible', true)
                                            gt('expenses', new BigDecimal(0))
                                        }
                                    }
                                }
                            }
    }
    }

The thing is: hours is an attribute from a specific class, the class that has this named query. And rates is a list nested in one of the nested objects on my specific class. When I try to use it there I'm getting:

java.lang.IllegalArgumentException: object is not an instance of declaring class

How do I refer to the hours attribute using this named query? Also one more question... it will return true if there is any item on rates list that returns true for this condition, correct?

That's my domain class:

class TravelDetail {

    Date date
    Country country
    BigDecimal hours
    BigDecimal mileage
    BigDecimal travel
    BigDecimal expenses

Into country I have:

class Country {

static hasMany = [rates: Rate

And into Rate I have:

class Rate {

    Boolean hoursEligible = Boolean.TRUE
        Boolean travelTimeEligible = Boolean.TRUE
        Boolean mileageEligible = Boolean.TRUE
        Boolean expensesEligible = Boolean.TRUE

Solution

  • Split the rate conditions in every and, something like this,

    country {
        and {
            between('effectiveDate', startDate, endDate)
            or {
                and {
                    rates {eq('hoursEligible', true)}
                    gt('hours', new BigDecimal(0))
                }
                .
                .
                and {
                    rates {eq('expensesEligible', true)}
                    gt('expenses', new BigDecimal(0))
                }
            }
        }
    }