So, during a bulk data load I'm building a massive tree of domain objects, checking for internal consistency, creating references between them... lots of processing. Then while saving, I'm batching the saves through calling session.clear() every 20 records or so.
My problem is that referenced domain objects are detached from the session when it's clear, so when I try to cascade the save, I get the expected a different object with the same identifier value was already associated with the session
Fragment of the domain model (cascade settings are not explicit in any classes):
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
}
There are a few more layers, and a lot more breadth to each layer, every Domain carries a reference to "School" for ease of searching. In the service, these objects are all built with a reference to the persisted school.
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() fails, non-unique ID of 1, I can check r.school.isAttached() and it's false. So I change it to...
...
session.clear()
r.school = School.get(r.school.id)
log.info("Attached now? ${r.school.isAttached()}") //shows true
r.save(failOnError:true)
}
r.save() fails again, and predictably, r.teacher[0].school.isAttached() is false...
Do I have to manually walk this ridiculous tree and reset every child object's reference to the refreshed "school" object? I feel I must be just missing something or doing something crazy wrong.