Search code examples
grailsgrails-orm

grails search with where on a hasmany


So, been trying to run a search in grails, and just can't figure out whats going on.

The app have two domains, a country map (called country) and the second one is regstat, which contains data on each country. I set it up so that country has many regstat, and regstat belongs to country. (have pasted the definition in the end). So, trying to make a call where I get the regstat entry based on country and reg.

    def countdata(String sn, String regsel) {

    def cpp = Regstat.where {
        domain { countryiso == sn }  && reg == regsel
    }

    render cpp as JSON   
}

Gives me the following error message.

    /GenMap/getcountry/countdata
Class
groovy.lang.MissingMethodException
Message
No signature of method: grails.gorm.DetachedCriteria.domain() is applicable for argument types: (genmap.GetcountryController$_countdata_closure1_closure10_closure11) values: [genmap.GetcountryController$_countdata_closure1_closure10_closure11@5dbfaacf] Possible solutions: min(), join(java.lang.String), min(java.lang.String), join(java.lang.String), min(groovy.lang.Closure), min(java.util.Comparator)

I also tried using country

def countdata(String sn, String regsel) {

    def cpp = Regstat.where {
        country { countryiso == sn }  && reg == regsel
    }

    render cpp as JSON   
}

This give me the following error message (in JSON web return)

{"alias":null,"async":{"decorators":[{"class":"com.sun.proxy.$Proxy40"}],"gormOperations":{"_ref":"..","class":"grails.gorm.DetachedCriteria"},"persistentClass":{"internalPromise":{"bindErrorManager":{"bindErrorListeners":[],"class":"groovyx.gpars.dataflow.impl.DataflowChannelEventOrchestrator","listeners":[]},"bound":false,"error":false,"eventManager":{"bindErrorListeners":[],"class":"groovyx.gpars.dataflow.impl.DataflowChannelEventOrchestrator","listeners":[]}

So has two domains. One is a country map.

    class Country {
    static hasMany = [regstats: Regstat]
    String countryiso
    String countryname
    static constraints = {
        countryiso size:2..2, unique: true, validator:{ it.toUpperCase() == it }
    }
    static mapping = {
        index: 'countryiso'
    }
}

And reg stat

class Regstat {
    static belongsTo = [country: Country]
    String reg
    int status
    String exturl
    Date impdate
    Date lupdate
    String impnote
    static constraints = {
        reg(inList: ["FATCA", "ITC2014", "AEOI"], unique:'country')
        exturl(nullable:true)
        impnote(nullable:true)
        impdate(nullable:true)
    }
    static mapping = {
        index: 'reg'
        impnote type: 'text'
    }
}

Update following the first response Also tried

def countdata(String sn, String regsel) {

def cpp = Regstat.where {
    country.countryiso == sn  && reg == regsel
}

render cpp as JSON   

}

Got the following error message (and garbled JSON output)

| Error 2014-10-08 10:56:24,532 [http-bio-8080-exec-1] ERROR errors.GrailsExceptionResolver  - NullPointerException occurred when processing request: [GET] /GenMap/getcountry/countdata - parameters:
sn: RU
regsel: FATCA
Stacktrace follows:
Message: null
    Line | Method
->>   82 | <init>                  in groovyx.gpars.serial.SerialHandle
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
|     41 | <init>                  in     ''
|    174 | <init> . . . . . . . .  in groovyx.gpars.serial.SerialHandle$LocalSerialHandle
|    172 | <init>                  in     ''
|    165 | create . . . . . . . .  in groovyx.gpars.serial.SerialHandle
|     62 | getOrCreateSerialHandle in groovyx.gpars.serial.WithSerialId
|    202 | value . . . . . . . . . in grails.converters.JSON
|    162 | convertAnother          in     ''
|    202 | value . . . . . . . . . in     ''
|    162 | convertAnother          in     ''
|    202 | value . . . . . . . . . in     ''
|    162 | convertAnother          in     ''
|    202 | value . . . . . . . . . in     ''
|    134 | render                  in     ''
|    150 | render . . . . . . . .  in     ''
|     15 | countdata               in genmap.GetcountryController$$EOs5m7Ro
|    198 | doFilter . . . . . . .  in grails.plugin.cache.web.filter.PageFragmentCachingFilter
|     63 | doFilter                in grails.plugin.cache.web.filter.AbstractFilter
|   1142 | runWorker . . . . . . . in java.util.concurrent.ThreadPoolExecutor
|    617 | run                     in java.util.concurrent.ThreadPoolExecutor$Worker
^    745 | run . . . . . . . . . . in java.lang.Thread

Solution

  • From the documentation:

    Associations can be queried by using the dot operator to specify the property name of the association to be queried:

    This will probably work:

    def cpp = Regstat.where {
        country.countryiso == sn && reg == regsel
    }
    return cpp.list() as JSON
    

    Hope that helps