I'm new in groovy and grails. Grails version 2.5.1 Groovy version 2.4.5 My problem is: I have an update method in customerController.
customerController:
def update(){
def map = [:]
def customerId = params.id
def newCustomer = request.JSON
def customer = customerService.updateCustomer(customerId, newCustomer)
customer.validate()
if (customer== null) {
map['success'] = false
map['message'] = "Record not found"
return map
}
if (customer.save()) {
map['success'] = true
map['data'] = customer
} else {
validateErrorService.extractErrors(customer, map)
}
return map
}
In update method I call customerService.updateCustomer
customerService:
def updateCustomer(customerId, newCustomer){
def customer = Customer.get(customerId)
if (customer == null) {
return null
}
verifyLead(newCustomer.leadId)
customer.firstName = newCustomer.firstName
customer.lastName = newCustomer.lastName
if(!customer.hasErrors())
customer.save(flush:true)
return customer
}
Then i call verifyLead method to update Lead domain
def verifyLead(jsonLead, userId){
Long leadId = jsonLead.id as Long
Lead lead = Lead.get(leadId)
lead.status = "Proceed"
lead.save(flush: true)
}
In lead domain method Lead.get(leadId) return old(cached) data So when i save: lead.save(flush: true) it error hibernate.object.staleException
(I'm speculating here, because I don't know your setup)
Short answer:
Often a StaleObjectStateException (which I suppose you get) occurs when the database record behind a domain object (in your case the Lead) has been updated between the last time it is read from DB and your save()
call.
Depending on your setup it could be a second instance of your Grails application.
One possible solution could be pessimistic locking (see 7.3.5 Pessimistic and Optimistic Locking in the Grails Documentation).
Longer answer (excuse me if you already know the more technical background):
get()
returns a domain object from the underlaying Hibernate session. This session does not recognize changes in the database automatically.
So if the DB changes then data in your Hibernate session may get stale.
GORM (DB layer of Grails) normally uses optimistic locking (tries to save and increases the value the version
field of the DB record).
If the version of the domain object your code tries to save is lesser than the version of the object in the db then GORM/Hibernate thinks better to throw an exception than to update the record and possibly destroy newer changes.
With pessimistic locking your code locks the DB record or table first, then updates the record, and at last releases the lock.
But be careful: pessimistic locking brings its own problems with it.