Grails, AJAX - Row was updated or deleted by another transaction

177 Views Asked by At

I have got a very simple gsp-Page with a list of objects and the possibility to edit each of them by clicking on a row. Once clicked a row I fetch the corresponding data via an AJAX call an present the details in some textfields below the table.

I then click on the "update" button resulting in another AJAX POST request sending the data to the corresponding controller which looks like the following:

def update(Role roleInstance) {
    if (roleInstance == null) {
        notFound()
        return
    }

    if (roleInstance.hasErrors()) {
        response.status = 420
        render template: "editForm", model: [roleInstance: roleInstance]
        return
    }

    roleService.update(roleInstance)

    flash.message = message(code: 'default.updated.message', args: [message(code: 'aedb.role.label'), roleInstance.authority])
    render template: "roleTable", model: [roleInstanceList:Role.list()]
}

Everything seems works fine - the domain objects are updated correctly in the database.

There's only one thing I don't understand: Everytime I click on a row in the table in order to fetch the data, change something and subsequently click the update button I get the StaleObjectStateException. If click the update button again the update succeeds without problem.

Currently, I'm saving the objects using the save method of the RoleService. Before that I tried to save it directly from the controller with roleInstance.save flush:true. However, then I got the same error when I did two updates of the same object quite fast after each other.

EDIT:

Following the source for my edit action in the RoleController:

def edit(Role roleInstance) {
    if (roleInstance == null) {
        notFound()
        return
    }

    def notAssignedPermissions = Permission.list() - roleInstance.getPermissions()
    render template: "editForm", model: [roleInstance: roleInstance, notAssignedPermissions: notAssignedPermissions]
}

And the RoleService which is quite a simple class in my case:

@Transactional
class RoleService {

    @Transactional(readOnly = true)
    def getRole(id) {
        Role.get(id)
    }

    @Transactional
    def update(role) {
        role.save()
    }
}
0

There are 0 best solutions below