Thanks Steve, that really cleared up what I'm seeing!
Quote:
No, if you later explicitly loaded the UOWData instance in a different session (as opposed to truly maintaining the original reference to it and re-attaching), then the associated collection would be lazy (because that is what you have specified in your mapping) and attempting to access that outside the session would result in a LazyInitializationException.
That sounds reasonable, but I assume that if I access the Sets within the new session that loads the UOWData, they would get initialized. I would then be able to close the session and read the Sets outside the session without getting a LazyInitializationException, right? That is, unfortunately, not what I'm seeing.
Here's what I really try to do. I have an instance of UOWData, populated outside a session. I open a session and start a transaction, call session.saveOrUpdate(uowData), and commit. Other threads in my application may have modified the UOWData in the database, so the saveOrUpdate() may throw a StaleObjectStateException. In this case I want to programatically do what a user would do in this situation: load the current UOWData state into an instance in a session, repopulate the Set members with new data, and try the saveOrUpdate() again. This works. But when I then try to access a Set outside a session, I get a LazyInitializationException.
In code, it goes something like this:
Code:
// In an earlier session, load the UOWData instance and populate its Sets.
private void save(UOWData uowData) {
Session session = factory.openSession();
Transaction tx = session.beginTransaction();
session.saveOrUpdate(uowData);
try {
tx.commit();
}
catch (StaleObjectException e) {
tx.rollback();
session.close();
reloadAndPopulate(uowData);
save(uowData);
}
session.close();
}
private void reloadAndPopulate(UOWData uowData) {
Session session = factory.openSession();
session.load(uowData, uowData.getId());
// Repopulate all Sets from copies with the new data, i.e.,
// uowData.getNfrontData().clear();
// uowData.getNfrontData().addAll(newNfrontDataValues);
...
// Just to be sure the proxies are really initialized, access them all, i.e.,
// uowData.getNfrontData().isEmpty();
...
}
Calling save() always works, even if the state in the database has changed so that the relaodAndPopulate() method gets invoked. After save(), if I try to read the Sets, it works fine if save() didn't call reloadAndPopulate() and it fails with LazyInitializationException if it did call reloadAndPopulate().
I'd appreciate any pointers to what I'm doing wrong.
Thanks.