Grails 2.4 REST домен с составным идентификатором

#json #grails

#json #grails

Вопрос:

Заранее спасибо за любые предложения. У меня есть устаревшая база данных, и у меня возникают проблемы при выполнении операций со списком с помощью REST JSON.

Таблицы БД:

 1) vm_properties (to keep key-value properties)
    vm_id int(25) PK 
    vm_key varchar(25) PK 
    vm_value longtext

2) vms table (I guess it should have been vm but as I said it is legacy exxisting db I need to expose CRUD operations using REST-JSON)
    vm_id int(11) AI PK 
    user_id int(11) 
   (.. there are other fields but I guess irrelevant for this problem)
  

Классы домена:

 1) VmProperties:

class VmProperties implements Serializable {
        Integer vm_id
        String vm_key
        String vm_value

        int hashCode() {
            def builder = new HashCodeBuilder()
            builder.append vm_id
            builder.append vm_key
            builder.toHashCode()
        }

        boolean equals(other) {
            if (other == null) return false
            def builder = new EqualsBuilder()
            builder.append vm_id, other.vm_id
            builder.append vm_key, other.vm_key
            builder.isEquals()
        }

        static belongsTo = [Vms]

        static mapping = {
            table 'vm_properties'
            id composite: ["vm_id", "vm_key"]
            version false
        }

        static constraints = {
            vm_value nullable: true
        }
    }

2) Vms:
class Vms {
    Integer vmId
    Integer user_id

    static hasMany = [vmPropertieses: VmProperties]

    static constraints = {
        user_id blank:false, nullable:false
    }

    static mapping = {
        table 'vms'
        version false
        id name:'vmId', column:'vm_id', sqlType:'int'
        vmId insertable:false, updateable:false

    }
}
  

Сгенерированные контроллеры:

 1) vm_properties
class VmPropertiesController extends RestfulController {
    static responseFormats = ['json', 'xml'] 
    static allowedMethods = [save: "POST", update: "PUT", delete: "DELETE"]

    def index(Integer max) {
        params.max = Math.min(max ?: 10, 100)
        respond VmProperties.list(params), model:[vmPropertiesInstanceCount: VmProperties.count()]
    }

    def show(VmProperties vmPropertiesInstance) {
        respond vmPropertiesInstance
    }
}

2) VmsController - nothing special... looks same as VmPropertiesController
  

Я могу сделать /testapp / vms и я получаю список виртуальных машин в формате JSON. Проблем нет. Но когда я делаю /testapp/vmProperties, я получаю эту ошибку: Нет такого свойства: vmId…. Я вижу, что это свойство есть в этой строке.

     Application starting ... 
    current environment: DEVELOPMENT
    now running in DEV mode.
....errors.GrailsExceptionResolver MissingPropertyException occurred when processing request: [GET] /passfarm/VmProperties
No such property: vmId for class: org.codehaus.groovy.grails.web.json.JSONObject$Null. Stacktrace follows:
groovy.lang.MissingPropertyException: No such property: vmId for class: org.codehaus.groovy.grails.web.json.JSONObject$Null
    at testapp.domain.VmProperties.equals(VmProperties.groovy:30)
    at grails.converters.JSON.value(JSON.java:176)
    at grails.converters.JSON.convertAnother(JSON.java:162)
    at grails.converters.JSON.value(JSON.java:202)
    at grails.converters.JSON.render(JSON.java:134)
    at grails.rest.render.json.JsonCollectionRenderer.renderJson(JsonCollectionRenderer.groovy:48)
    at org.grails.plugins.web.rest.render.json.DefaultJsonRenderer.renderJson(DefaultJsonRenderer.groovy:110)
    at org.grails.plugins.web.rest.render.json.DefaultJsonRenderer.render(DefaultJsonRenderer.groovy:91)
    at org.grails.plugins.web.rest.api.ControllersRestApi.respond(ControllersRestApi.groovy:177)
    at org.grails.plugins.web.rest.api.ControllersRestApi.respond(ControllersRestApi.groovy:75)
    at testapp.controller.VmPropertiesController.$tt__index(VmPropertiesController.groovy:25)
    at grails.plugin.cache.web.filter.PageFragmentCachingFilter.doFilter(PageFragmentCachingFilter.java:198)
    at grails.plugin.cache.web.filter.AbstractFilter.doFilter(AbstractFilter.java:63)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:724)
  

Комментарии:

1. В Vms классе вы сопоставляете vmId свойство с vm_id полем в БД. Попробуйте сделать то же самое в VmProperties классе. Переименуйте vm_id и сопоставьте его. Есть некоторые базы данных, которые не принимают некоторые имена таблиц и столбцов. Но я не знаю, какая ситуация у вас на самом деле.

2. Вы когда-нибудь находили решение для этого? У нас возникла почти идентичная проблема с использованием составных ключей в Grails 2.4.4