Hibernate version: 3.1
We have a rich object graph. Basically we have a Project, which contains ProjectResources and ProjectActivity's. When resources are assigned to the activity, the ProjectActivity contains ProjectActivityAssignment's. A ProjectActivityAssignment contains the reference to the ProjectActivity and the ProjectResource. The ProjectResource contains references to the Project and a Resource. A Resource contains a collection of Calendar (our object) objects (defines working time). Graphically...
Code:
Project
|
---ProjectResource (collection)
|
---ProjectActivity (collection)
|
---ProjectActivityAssignment (collection)
|
---ProjectActivity
|
---ProjectResource (same object as in project's collection)
|
---Project
|
---Resource
|
---CalendarAssignment (collection)
|
---Calendar
There's more but for simplicity's sake...
When I modify a ProjectActivity I first load it, and present it to the user for modification. Most of the collections are proxy's and in particular from about ProjectResource down everything is a lazy loaded proxy. The ProjectActivity obviously becomes detached while being presented to the user. When it comes time to save it I have to calculate a new end date for the ProjectActivity by taking the start date, the effort, which calendar each of the project resources is assigned to in order to work out a velocity to come up with an end date. I also have to do the same with any ProjectActivity that is dependant on the one just modified. I achieve both of these by telling the Project to recalculate itself starting from the specified ProjectActivity object.
I would call update() on the Activity prior to trying call activity.getProject().recalculate( activity) in order to have the ProjectActivity attached to a current session. But the proxy's would not be resolved, and when I tried to calculate an end date I'd get a LazyLoadException.
I solved this by calling merge() on the ProjectActivity instead. This seems to propogate the changes and resolve all the proxy'd objects into proxy's that can be travered in the current session. Great.
I have tried doing something similar on creating a ProjectActivity. However I can't call merge() on the ProjectActivity because it is an unsaved transient. Fine, that's understandable. So I call saveOrUpdate on the new ProjectActivity which persists it and gives it a new database identifier. However all the objects further down the graph are still proxy's from the previous session and I still get a LazyLoadException.
So then I tried saving it, and then immediately loading it again, in order to (theoretically) have everything associated with the current session. Same problem. I have only been able to get around this by traversing all of the ProjectActivity's ProjectResourceAssignment objects, and calling refresh() on the associated ProjectResource. Then it seems to work.
However this seems at odds with how Hibernate is supposed to work from what I've read on this forum, the reference doc, and how (relatively) easily persistence has been in other areas of our application. Is there a key point I'm missing here?
Thanks, Andrew