0

因此,在批量数据加载期间,我正在构建一个庞大的域对象树,检查内部一致性,在它们之间创建引用......大量处理。然后在保存时,我通过每 20 条左右的记录调用 session.clear() 来批量保存。

我的问题是引用的域对象在明确时与会话分离,因此当我尝试级联保存时,我得到预期的具有相同标识符值的不同对象已经与会话相关联

域模型的片段(级联设置在任何类中都不是明确的):

class School {
  String name
}

class Room {
  String roomNum
  School school
  static belongsTo = School 
  static hasMany = [teachers:Teacher]
}

class Teacher {
  String name
  Room room
  School school
  static belongsTo = Teacher
  static hasMany = [students:Stuent]
}

class Student {
  String name
  Teacher teacher
  School school
  static belongsTo = Student
}

还有几层,每一层的广度也更大,每个域都带有“学校”的引用,以便于搜索。在服务中,这些对象都是通过对持久学校的引用来构建的。

def buildData() {
 School s = School.get(1)
 Room r = new Room(name: "A", school: s)
 Teacher t = new Teacher(room: r, school: s, name: "Smith")
 r.addToTeachers(t)
 Student s = new Student(teacher: t, school: s, name: "Billy")
 t.addToStudents(s)

 //ad nauseum
}

def persistData() {
  //lots of processing
  def session = sessionFactory.currentSession
  session.flush()
  session.clear()
  ........
  r.save(failOnError:true)
}

r.save() 失败,非唯一 ID 为 1,我可以检查 r.school.isAttached() 并且它是错误的。所以我把它改成...

...
session.clear()
r.school = School.get(r.school.id)
log.info("Attached now?  ${r.school.isAttached()}")  //shows true
r.save(failOnError:true)
}

r.save() 再次失败,并且可以预见, r.teacher[0].school.isAttached() 是错误的......

我是否必须手动走过这棵荒谬的树并重置每个子对象对刷新的“学校”对象的引用?我觉得我一定是错过了什么或做错了什么疯狂的事情。

4

2 回答 2

2

像往常一样,我对它进行了足够的冲击,并在正确的地方寻找,我通常会弄清楚。

更换

r.school = School.get(r.school.id)

r.school.attach()  

通过重新附加内存中的引用而不是加载新的引用并将 r.school 的实例设置为不同的实例来解决此问题。通过调试和查看对象编号确认这是发生的。

我以为我过去曾这样做过,并且在附加到会话时遇到了问题,但我一定是弄错了。

于 2013-10-07T13:12:42.823 回答
0

附上作品。get 很特别,因为它首先在本地查找,以避免数据库命中与负载(见下文):

休眠:session.get 和 session.load 之间的区别

此外, findById 始终有效。

于 2015-02-04T17:17:26.313 回答