使用数据绑定更新多对多关系时索引超出范围

时间:2013-07-08 02:45:55

标签: grails gorm

我有更新具有多对多关系的域的问题。例如,考虑这两个简单的域。

class Student {
   String name
   static hasMany = [courses: Course]
}

class Course {
  String name
  static hasMany = [students: Student]
  static belongsTo = [Student]
}

要更新学生的姓名及其课程名称,我使用这样的数据绑定:

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)

但是,这会导致错误:

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

经过一番搜索后,我发现所有答案都建议使用List for relation而不是Set。但是,我仍然喜欢使用Set。

环境

  • Grails:2.2.3
  • Java:1.6.0_45
  • OS:Ubuntu 13.04

2 个答案:

答案 0 :(得分:1)

我的解决方案是在数据绑定之前清除子列表。这是测试上述域的完整代码。第s1.courses.clear()行会阻止上述错误。

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)

但是,我仍然认为这个问题是一个错误。我的解决方案是一个解决方案。

答案 1 :(得分:0)

未订购Set,因此如果指定索引,它将失败。

如果您不想使用List,请尝试使用SortedSet。

您可以找到更多信息@(http://grails.org/doc/latest/guide/single.html#ormdsl)6.5.3默认排序顺序