I have problem for updating domain that has many-to-many relation. For instance, consider these 2 simple domains.
class Student {
String name
static hasMany = [courses: Course]
}
class Course {
String name
static hasMany = [students: Student]
static belongsTo = [Student]
}
To update student's name along with his/her courses' name, I use data binding like this:
def params = [
'courses[0].id': c2.id,
'courses[0].name': 'c11',
'courses[1].id': c1.id,
'courses[1].name': 'c22'
]
s1.properties = params
s1.save(flush: true)
However, this will cause error:
org.springframework.beans.InvalidPropertyException: Invalid property 'courses[1]' of bean class [tb.Student]:
Invalid list index in property path 'courses[1]'; nested exception is java.lang.IndexOutOfBoundsException:
Index: 1, Size: 1
After some searching, I found that all answers suggest to use List for relation instead of Set. However, I still prefer to use Set.
Environment
My solution is to clear the children list before data binding. This is the full code to test above domains. The line s1.courses.clear()
will prevent above error.
def s1 = new Student(name: 's1').save(flush: true)
def s2 = new Student(name: 's2').save(flush: true)
def c1 = new Course(name: 'c1').save(flush: true)
def c2 = new Course(name: 'c2').save(flush: true)
s1.addToCourses(c1)
s1.addToCourses(c2)
s1.save(flush: true)
def params = [
'courses[0].id': c2.id,
'courses[0].name': 'c11',
'courses[1].id': c1.id,
'courses[1].name': 'c22'
]
s1.courses.clear()
s1.properties = params
s1.save(flush: true)
However, I still think this problem is a bug. And my solution is a work around.