Reputation: 1199
I was creating a new grails app with several domain classes and controllers. All my controllers have working methods for save(), update() and list(), e.g.
def update(Long id, Long version) {
def crawlerConfigInstance = CrawlerConfig.get(id)
if (!crawlerConfigInstance) {
flash.message = message(code: 'default.not.found.message', args: [message(code: 'crawlerConfig.label', default: 'CrawlerConfig'), id])
redirect(action: "list")
return
}
if (version != null) {
if (crawlerConfigInstance.version > version) {
crawlerConfigInstance.errors.rejectValue("version", "default.optimistic.locking.failure",
[message(code: 'crawlerConfig.label', default: 'CrawlerConfig')] as Object[],
"Another user has updated this CrawlerConfig while you were editing")
render(view: "edit", model: [crawlerConfigInstance: crawlerConfigInstance])
return
}
}
crawlerConfigInstance.properties = params
if (!crawlerConfigInstance.save(flush: true)) {
render(view: "edit", model: [crawlerConfigInstance: crawlerConfigInstance])
return
}
flash.message = message(code: 'default.updated.message', args: [message(code: 'crawlerConfig.label', default: 'CrawlerConfig'), crawlerConfigInstance.id])
redirect(action: "show", id: crawlerConfigInstance.id)
}
which is actually an autogenerated / scaffolded method by IDE
However, now I was adding an additional controller method which should run through a list of domain objects and update them accordingly. Getting the list, changing the attributes and validation is successfull.
save(flush:true) doesn't throw any errors and returns the updated domain object, as expected. However, checking the hibernate SQL statements, all I see is SELECTS, no update. In fact, if I directly call a delete() on the domain object after the save(), I get a concurrent transaction exception on the domain object.
My controller method looks like
def doSomething() {
def results = CrawlerConfig.findAll(bQ)
results.each { crawlerConfigInstance ->
crawlerConfigInstance.needsReview = true
if (!crawlerConfigInstance.save(flush: true)) {
render(view: "show", model: [crawlerConfigInstance: crawlerConfigInstance])
return
}
}
redirect(action: "list")
}
Pretty straightforward. If I check for the dirty fields, needsReview is marked as dirty before the save(). save() updates the version on the object.
I currently still use h2:mem as database.
For me it looks like the transaction is not finished. But I don't get why or how I can get it to finish.
Thx in advance
EDIT after POST from Ondrej
created a Service (which gets injected and called fine)
package lizard
import org.springframework.transaction.annotation.Transactional
@Transactional class CrawlerConfigPersistenceService {
static transactional = true
def checkRequirementsForCrawlerConfigList(String query) {
def results = CrawlerConfig.findAll(query)
results.each { crawlerConfigInstance ->
crawlerConfigInstance.needsReview = true
if (!crawlerConfigInstance.save(flush: true)) {
println crawlerConfigInstance.errors.getAllErrors()
return
}
}
}
}
But this results in exactly the same behaviour, everything looks OK, except that there is no update statement raised by hibernate
Upvotes: 0
Views: 2873
Reputation: 4643
Move your methods for save(), update() and list() from Controllers to Services. Before doing it, have a look here and read the Services chapter: http://grails.org/doc/latest/guide/services.html
Upvotes: 0