Reputation: 122
I'm trying to persist a one-to-many relationship in Grails with the following domain classes. A user should have many tasks (and a task should have a reference to its user).
User.groovy
package helloworld
class User {
String name
String password
Date register_date
static hasMany = [tasks: Task]
static mapping = {
tasks cascade: "all-delete-orphan"
}
static constraints = {
}
}
Task.groovy
package helloworld
class Task {
String description
Date due
Boolean deleteFinished
Boolean finished
static belongsTo = [owner: User]
static constraints = {
}
}
TodoController.groovy (the problem?)
...
def persist() {
User u = User.get(session["user_id"])
Boolean df = params["deleteFinished"] != null
Task t = new Task(description: params["description"], due: params["due"], deleteFinished: df, finished: false)
u.addToTasks(t)
u.save(flush: true) //problem point
redirect(action: 'index')
}
...
So according to all documentation I've read the hibernate session is supposed to be flushed and closed at the end of every request, but that doesn't seem to be the case here. u.save(flush: true)
works as it should, persisting any changes or added children (Task t), but when I use u.save()
any changes made to u as well as Task t
don't get persisted after the end of the request. What's even more bizarre, if I move the code to a Grails service with transaction encapsulated methods, u.save()
works. I've checked everything I can think of. My domain objects are attached, they are valid, they detect that they're dirty when they change. Can anyone help me figure out this mystery?
Upvotes: 0
Views: 643
Reputation: 1139
Controllers don't have transactions enabled by default. Moving the code to a service (they are transactional by default) or annotating your method as transactional should solve your problem.
import grails.transaction.Transactional
@Transactional
def persist() {
User u = User.get(session["user_id"])
Boolean df = params["deleteFinished"] != null
Task t = new Task(description: params["description"], due: params["due"], deleteFinished: df, finished: false)
u.addToTasks(t)
u.save()
redirect(action: 'index')
}
Upvotes: -1