|
From: James C. <jim...@do...> - 2005-05-03 14:45:26
|
That's the best summary yet, Juergen. Thanks.
> In case of a rollback, the Session will receive a clear() call which
> resets all of its pending updates/deletes. This avoids side effects=20
> from dirty state created during the transaction that has just been=20
> rolled-back. Any further transactions can still properly load and=20
> modify persistent objects and expose them to views, with lazy=20
> loading still working.
I like the fact that you clear the session on rollback. Perhaps that =
same
logic could be applied to prevent a potential side-effect of this =
pattern.
Here is a series of steps to reproduce an unintentional save of an =
object in
invalid state.
1. Browser request made, Hibernate session created, web controller
instantiated.
2. Controller loads object X.
2a. tx.begin
2b. X =3D session.load(id, class)
2c. session.flush
2d. tx.commit
3. X is now a detached object in the controller.
4. Apply request properties against X.
5. Validate X.
6. X is invalid, return to view.
7. View invokes lazy-load of a collection on X (no prob)
8. Some component of the view needs a collection of reference objects.
8a. View calls controller.getReferences()
8b. tx.begin
8c. refs =3D session.find("from somereference")
8d. session.flush()
8e. tx.commit
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).
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.
There are other workarounds that may be jammed in, but the ones I can =
think
up are not exactly elegant. Perhaps this is simply a case of developer
beware; a known side-effect to using the OSIV approach to web =
development.
I'd appreciate any advice on whether the framework can be coerced to
eliminate one of the remaining flaws in this pattern.
> BTW, TopLink is *very* different in that respect: while it does have a
> Session concept too, it handles persistent object lifecycle and in
> particular lazy loading very differently (there is no need for Open
> Session in View there in the first place, as lazy loading will always
> work).
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.
|