|
From: Juergen H. <ju...@in...> - 2005-05-04 14:43:01
|
James, > The invalid object X will be inadvertently persisted to the database in step > 8. It also occurs in a manner that can be very hard to anticipate or debug > depending on how step 8 is triggered. > > The view component that loads the reference objects (8) does not even have > to be the same view that invokes the lazy load (7). For example, the > developer may be using sitemesh or tiles and a page composition component > may have triggered (8). Yes, that risk is unfortunately hard to avoid. What you need to here is to mark all your reference data access operations as "readOnly" in the Spring transaction demarcation, to suppress the flush there. However, if you wanted to execute a read-write transaction after you modified the loaded Hibernate object, you would have the same problem again... "readOnly" helps to keep the risk low, but it does not avoid it completely. > One technique to address this problem might be to clear the session *prior* > to the start of a transaction. This is not ideal, because sometimes the > controller may wish to invoke multiple transactional methods without losing > the session state. Session.clear is a very strong operation: it essentially evicts all loaded objects from the first-level cache. This has the effect of clearing pending modifications to persistent objects, but also of making all existing persistent instances invalid and not capable of lazy loading anymore. Alternatively, you could evict specific objects from the Session - but those wouldn't be lazy loading capable anymore either. So I'm afraid there is no proper 100% solution for this problem: If you modify a persistent object within OSIV in "single session" mode and do not want to persist those changes in the same request, make sure that all transactions that follow within the same request are read-only. The only other alternative that comes to my mind is OSIV in "deferred close" mode, with Hibernate3 merge instead of saveOrUpdate/update. This should work pretty well, although I haven't battle-tested that combination yet. In particular, merge should not show the side effects that saveOrUpdate has on persistent objects that are still registered with a different Hibernate Session. > I think OJB also handles lazy-loading differently than Hibernate, but I have > only read about it. Seems like OJB isn't gaining a foothold. Yes, OJB handles this more relaxed too, and so does iBATIS SQL Maps. It's only Hibernate and JDO that enforce such strict requirements on lazy loading. The root of the problem is that they tie lazy loading to their persistent object lifecycle and change detection machinery, which the others don't. TopLink is the best example that this can be designed differently (with relaxed lazy loading), while offering similar powers as Hibernate and JDO. Juergen |