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()
}
}