Search code examples
grailsgrails-ormhibernate-criteria

Including the max and offset criteria inside GORM criteriaBuilder returns an error


Can I make this code shorter?

if(count == null && from = null) {
    creditAdviceList = CreditAdvice.findAll {
        ilike('id', "%$idFilter%")
        .....
        ilike('statusCode', statusCodeFilter)
    }
}
else if(count != null && from == null) {
    creditAdviceList = CreditAdvice.findAll(max: count) {
        ilike('id', "%$idFilter%")
        .....
        ilike('statusCode', statusCodeFilter)
    }
}
else if(count == null && from != null) {
    creditAdviceList = CreditAdvice.findAll(offset: from) {
        ilike('id', "%$idFilter%")
        .....
        ilike('statusCode', statusCodeFilter)
    }
}
else if(count != null && from != null) {
    creditAdviceList = CreditAdvice.findAll(max: count, offset: from) {
        ilike('id', "%$idFilter%")
        .....
        ilike('statusCode', statusCodeFilter)
    }
}

You see, its a series if statement for each possible scenario. Imagine if one would to use also order and cache in the parameter- there will be basically 16 unique if statements!

I've tried this [more] shorter code:

creditAdviceList = CreditAdvice.findAll {
    ilike('id', "%$idFilter%")
    .....
    ilike('statusCode', statusCodeFilter)

    if(count != null) {
        maxResults(count)
    }
    if(from != null) {
        firstResult(from)
    }
}

But it gives me an error:

...No signature of method: grails.gorm.DetachedCriteria.maxResults() is applicable for argument types: (java.lang.Integer)...

I tried to convert offset to int, Integer, String, etc. I also omit the if statement inside the criteria, but the same error message occur.


Solution

  • findAll with a closure passed is using a DetachedCriteria internally, which is not the same as the result you would get from createCriteria mentioned in the docs. If groovy would find "something close" enough, it would tell you in the error message. The easiest way to deal with your max/from demands would be with simply with a map (which is the first argument passed). E.g.:

    def qcfg = [:]
    if (count) {
        qcfg.count = count
    }
    if (from) {
        qcfg.offset = from
    }
    creditAdviceList = CreditAdvice.findAll(qcfg) { ... }
    

    mix, match, extract, shorten as you see fit