When executing PUT method in application Grails system inserts new record instead of updating

1

When trying to run JSON below via PUT method in a Grails application the system inserts a new record.

URLMappings.groovy

class UrlMappings {

static mappings = {
    "/$controller/$action?/$id?(.$format)?"{
        constraints {
            // apply constraints here
        }
    }

    "/"(controller:"main")
    "500"(view:'/error')

    "/api/Patrimonio"(controller:"Patrimonio"){
        action = [GET:"showJSON", POST:"saveJSON", PUT:"updateJSON"]
    }

    "/api/Patrimonio/$id"(controller:"Patrimonio"){
        action = [GET:"showJSON", PUT:"updateJSON"]
    }

    "/api/Departamento"(controller:"Departamento"){
        action = [GET:"showJSON", POST:"saveJSON"]
    }

    "/api/Departamento/$id"(controller:"Departamento"){
        action = [GET:"showJSON", PUT:"updateJSON"]
    }

    "/api/Local"(controller:"Local"){
        action = [GET:"showJSON"]
    }

    "/api/Responsavel"(controller:"Responsavel"){
        action = [GET:"showJSON"]
    }

}
}

DepartmentController.groovy

package br.ufscar.dc.dsw

import static org.springframework.http.HttpStatus.*

import javax.persistence.criteria.CriteriaQuery;

import grails.converters.JSON
import grails.transaction.Transactional

import org.apache.tools.ant.types.resources.Restrict;
import org.hibernate.Criteria;
import org.hibernate.criterion.LogicalExpression;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Restrictions;
import org.springframework.security.access.annotation.Secured

import br.ufscar.dc.dsw.util.Constantes

@Secured(['ROLE_MEMBRO_COMISSAO', 'ROLE_SERVIDOR', 'IS_AUTHENTICATED_ANONYMOUSLY'])
@Transactional(readOnly = true)
class DepartamentoController {

    static allowedMethods = [save: "POST", update: "PUT", delete: "DELETE"]
    def registros

    def index() {
        params.max = Math.min(params.max ? params.int('max') : Constantes.MINIMO_PAGINACAO, Constantes.MAXIMO_PAGINACAO)
        registros = Departamento.createCriteria().list(params) {
            if (params.query) {
                if(params.tipo == "Sigla")
                    ilike("sigla", "%${params.query}%")
                else
                    ilike("nome", "%${params.query}%")
            }
        }
        respond registros, model:[departamentoInstanceTotal: registros.totalCount]
    }

    @Secured([
        'ROLE_MEMBRO_COMISSAO',
        'ROLE_SERVIDOR'
    ])
    def show(Departamento departamentoInstance) {
        respond departamentoInstance
    }

    @Secured('ROLE_MEMBRO_COMISSAO')
    def create() {
        respond new Departamento(params)
    }

    @Secured('ROLE_MEMBRO_COMISSAO')
    @Transactional
    def save(Departamento departamentoInstance) {
        if (departamentoInstance == null) {
            notFound()
            return
        }

        if (departamentoInstance.hasErrors()) {
            respond departamentoInstance.errors, view:'create'
            return
        }

        departamentoInstance.save flush:true

        request.withFormat {
            form multipartForm {
                flash.message = message(code: 'default.created.message', args: [
                    message(code: 'departamento.label', default: 'Departamento'),
                    departamentoInstance.id
                ])
                redirect departamentoInstance
            }
            '*' {
                respond departamentoInstance, [status: CREATED]
            }
        }
    }

    @Secured('ROLE_MEMBRO_COMISSAO')
    def edit(Departamento departamentoInstance) {
        respond departamentoInstance
    }

    @Secured('ROLE_MEMBRO_COMISSAO')
    @Transactional
    def update(Departamento departamentoInstance) {
        if (departamentoInstance == null) {
            notFound()
            return
        }

        if (departamentoInstance.hasErrors()) {
            respond departamentoInstance.errors, view:'edit'
            return
        }

        departamentoInstance.save flush:true

        request.withFormat {
            form multipartForm {
                flash.message = message(code: 'default.updated.message', args: [
                    message(code: 'Departamento.label', default: 'Departamento'),
                    departamentoInstance.id
                ])
                redirect departamentoInstance
            }
            '*'{
                respond departamentoInstance, [status: OK]
            }
        }
    }

    @Secured('ROLE_MEMBRO_COMISSAO')
    @Transactional
    def delete(Departamento departamentoInstance) {

        if (departamentoInstance == null) {
            notFound()
            return
        }

        departamentoInstance.delete flush:true

        request.withFormat {
            form multipartForm {
                flash.message = message(code: 'default.deleted.message', args: [
                    message(code: 'Departamento.label', default: 'Departamento'),
                    departamentoInstance.id
                ])
                redirect action:"index", method:"GET"
            }
            '*'{ render status: NO_CONTENT }
        }
    }

    protected void notFound() {
        request.withFormat {
            form multipartForm {
                flash.message = message(code: 'default.not.found.message', args: [
                    message(code: 'departamento.label', default: 'Departamento'),
                    params.id
                ])
                redirect action: "index", method: "GET"
            }
            '*'{ render status: NOT_FOUND }
        }
    }

    def exportar = {
        chain(controller:'jasper',action:'index',model:[data:registros],params:params)
    }

    @Secured([
        'IS_AUTHENTICATED_ANONYMOUSLY'
    ])
    def showJSON(Departamento patrimonioInstance) {
        if(params.id && Departamento.exists(params.id)){
            render Departamento.findById(params.id) as JSON
        }else{
            render Departamento.list() as JSON
        }
    }

    @Transactional
    @Secured([
        'IS_AUTHENTICATED_ANONYMOUSLY'
    ])
    def saveJSON() {
        if (request.JSON != null) {
            def jsonObject = request.JSON
            def departamento = new Departamento(jsonObject)
            save(departamento)
        }
        render status: OK
    }

    @Transactional
    @Secured([
        'IS_AUTHENTICATED_ANONYMOUSLY'
    ])
    def updateJSON() {
        if (request.JSON != null) {
            def jsonObject = request.JSON
            def departamento = new Departamento(jsonObject)
            update(departamento)
        }
    }
}

JSON Sent

{"nome":"TESTE", "sigla":"TE"}

I sent this JSON via PUT method by link only instead of updating the code record 6 it inserts a new record. I've seen Grails application debug that it is correctly calling the updateJSON method, however it does not update the registry ...

I'm using Grails 2.4.2

    
asked by anonymous 04.11.2015 / 10:25

1 answer

1

The record is being inserted because within the action updateJSON a new Department instance is being created and passed as a parameter to the update method. The update method, in turn, saves this instance. Since it does not exist, then a new record is inserted into the database.

To resolve, you need to get the instance you want to update in updateJSON , so you need to use some of the database search methods available from Grails (get, findBy, hql, . Here is an example of how this could be done using get:

def updateJSON() {
    if (request.JSON != null) {
        def jsonObject = request.JSON
        def departamento = Departamento.get(jsonObject.id)
        departamento.properties = jsonObject
        update(departamento)
    }
}

In the code above, an instance is being obtained using the get method by passing the Department ID. Once this is done, a Groovy (department.properties = jsonObject ) way of updating the attributes of an object is used.

Note that for this to work the fields in the jsonObject map must have the same name as the Department class attributes.

Another option to update the attributes is to use the bindData method, which is available in the Controllers.

See an example:

def updateJSON() {
    if (request.JSON != null) {
        def jsonObject = request.JSON
        def departamento = Departamento.get(jsonObject.id)
        bindData(departamento, jsonObject)
        update(departamento)
    }
}

Documentation: link

    
06.11.2015 / 12:28