javagrailsgrails-ormgrails-3.0grails3

How to access rows with composite keys in Grails?


I'm creating a simple CRUD for a Oracle 12c DB in Grails 3 using scaffolding and while for simple tables which have an explicit integer ID column like this one:

class Config {
    int id
    String name
    String type
    String value
    String description
    int status

    static constraints = {
        /* constraints constraints constraints */
    }

    static mapping = {
        sort 'name'
        version false
        id column: 'CONFIGID', name:'id', generator:'sequence', params:[sequence: 'CONFIG_SEQ']
    }
}

everything works fine and you can access a given row's scaffolded views through an auto-generated link in the list view as well as with an explicit URL in the form of config/<view>/<ID>, as soon as I have a table with a composite key like this one:

class AliasFrequencyDict implements Serializable{
    String frequency
    String unit
    String description
    String lang

    static constraints = {
        /* constraints constraints constraints */
    }

    static mapping = {
        sort 'frequency'
        version false
        id composite: ['frequency', 'unit', 'lang']
    }
}

... you can't access the rows anymore (or I don't know how). Scaffolding doesn't generate links to the views in list view anymore and trying to access it through a URL like aliasFrequencyDict/show/0/D/PL (which would precisely be /<view>/<frequency>/<unit>/<lang> like specified in the composite id's definition) results in a 404.

How do I access the relevant show, edit etc. pages when using a composite ID?


Solution

  • How do I access the relevant show, edit etc. pages when using a composite ID?

    There are many ways to do it. For example, for show you could have a URL mapping that looks something like this...

    "/aliasFreqDict/$freq/$unit/$language"(controller: 'aliasFreqDict', action: 'show')
    

    And then have a corresponding controller action...

    class AliasFreqDictController {
    
        AliasFreqService aliasFreqService
    
        def show(String freq, String unit, String language) {
            // have a service method that looks up the instance by these properties...
            respond aliasFreqService.find(freq, unit, language)
        }
    }
    

    I hope that helps.