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"]
}
}
}
Departamentocontroller.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 Enviado
{"nome":"TESTE", "sigla":"TE"}
I sent this JSON via PUT method at the address http://localhost:8080/Patrimonio/api/Departamento/6 only that instead of updating the code record 6 it inserts a new record. Via debug of the Grails application I saw that it is correctly calling the updateJSON method, however it does not update the record...
I’m using Grails 2.4.2
It is inserting, because within the updateJSON() you are creating a department and passing it to the update(). In update there is a save on this object. From what I understand of your problem, in the updateJSON you must recover an existing Department object and not create a new one.
– cantoni
Thanks for the answer, but the update method is correct. When I call it by the application the record is changed normally, the problem is when I call the updateJSON method. From what I saw, he’s entering the log because I wasn’t sending the ID. I made a new json by adding the id attribute, but it still gets NULL when creating the object through json....
– Thiago
Exactly @Thiago, when you call the update() of the application, you pass an instance of Department that already exists, you probably use a get or a findBy to find it in the bank. The problem is that updateJSON does not deliver an existing instance for the update. It creates a new instance and switches to the update. The save method, in turn, will enter a record. Try to put something like this on updateJSON: def department = Department.get(jsonObject.id) where jsonObject.id must be the id of an existing Department.
– cantoni
hmm got it. I did fetch the record, however how do I set the updated Json values in the object??
– Thiago