Search code examples
grailsgrails-controller

what is version parameter in generated controller's update method


I am doing a sample applications in grails I created a Sponsor domain class, then I generated its corresponding controller which is

class SponsorController
{
...

def update(Long id, Long version){

def sponsorInstance = Sponsor.get(id)
if (!sponsorInstance) {
flash.message = message(code:'default.not.found.message',args:message(code:'sponsor.label',
default: 'Sponsor'),
                id
            ])
            redirect(action: "list")
            return
        }

        if (version != null) {
            if (sponsorInstance.version > version) {
                sponsorInstance.errors.rejectValue("version", "default.optimistic.locking.failure",
                        [
                            message(code: 'sponsor.label', default: 'Sponsor')] as Object[],
                        "Another user has updated this Sponsor while you were editing")
                render(view: "edit", model: [sponsorInstance: sponsorInstance])
                return
            }
        }

        sponsorInstance.properties = params

        if (!sponsorInstance.save(flush: true)) {
            render(view: "edit", model: [sponsorInstance: sponsorInstance])
            return
        }

        flash.message = message(code: 'default.updated.message', args: [
            message(code: 'sponsor.label', default: 'Sponsor'),
            sponsorInstance.id
        ])
        redirect(action: "show", id: sponsorInstance.id)
    }

when I generated a controllers it generated list,show,save,create,edit and update methods. I understood all the methods code but I am little confused in update's method code in which it took two parameters id and version so my question is what is version here and what is the purpose of using version here


Solution

  • version is added to each domain class by default and is used to implement optimistic locking. Consider the following scenario

    • User A retrieves an instance of domain class
    • User B retrieves an instance of domain class
    • User A updates the instance
    • User B updates the instance

    If we simply allow user B's instance to persist he'll effectively overwrite the changes made by A. In some applications this might be OK, but in others, we might want to tell user B that the object has changed since he read it, and show him the changes instead of overwriting user A's update.

    The version property is how this scenario (known as a "dirty write") is detected, i.e. it is used to check that the version of an object that was read is the same version that is currently in the database. Each time an update is made to an object, the version column is incremented.