So far my answer is lazy="false" but I'm sure that mite bite me in the
a$$ when going to production and having a lot of users.  Pat, I think
I'm gonna try out your long-session thread pattern and see if that
fixes some of my issues.  If not that then to tap 4 and hiveutils...

On 8/30/05, Patrick Casey <[EMAIL PROTECTED]> wrote:
> 
>        I don't think that gets you around the lazy initialization problem
> though, does it? If the session closes when the servlet returns, then it's
> no longer available in subsequent interactions to load lazy collections.
> 
>        Likewise, globally rolling back the transaction isn't necessarily
> the right approach either (yet another gripe I have about how hibernate and
> the web fight one another).
> 
>        This is a slightly contrived example, but for purposes of
> explanation it should work:
> 
>        Lets say I need to log every user interaction to the DB (not that
> weird actually, I've had to do this on some security conscious apps).
> 
>        So whenever A user presses "save" on a web form I have to:
> 
>        Log an "interaction begun" datum with the IP address, session ID,
> etc.
>        Do the transaction.
>        Log an "interaction complete" datum with the UP address, session ID,
> etc.
> 
>        If I roll back globally, I lose not only the user's personal update
> (which I want to roll back), but also the interaction records, which I
> *don't* want to roll back.
> 
>        It's gotten so aggravating I'm seriously considering using two
> parallel session. One for "system" data that I have control of and one for
> "user" updates that I might have to roll back. That way I can always flush
> my system session and selectively flush the user session. Of course that
> means twice the number of DB connections, dogs and cats living together,
> etc, etc, etc.
> 
>        It's frustrating, as you can doubtless discern from my aggravated
> tone :(.
> 
>        --- Pat
> 
> > -----Original Message-----
> > From: Paul Cantrell [mailto:[EMAIL PROTECTED]
> > Sent: Tuesday, August 30, 2005 3:23 PM
> > To: Tapestry users
> > Subject: Re: Transaction handling. Where?
> >
> > If you open & close your ThreadLocal session from a *servlet filter*
> > instead of trying to finagle it into the tapestry lifecycle,
> > everything is peachy -- at least in my limited experience.
> >
> > For rollbacks, implement a preventCommit() method your code can call
> > on error. In the filter, you either commit or roll back depending on
> > whether preventCommit() was called.
> >
> > Cheers,
> >
> > Paul
> >
> > On Aug 30, 2005, at 4:22 PM, Patrick Casey wrote:
> >
> > >
> > >     Yah, I'm familiar with a large variety of ways to initialize
> > > collections. The problem with pre-initializing everything though is
> > > that
> > > most of the time, you *don't* need the whole object graph. So if I
> > > have to
> > > fill out every object graph every time I load a root object on the off
> > > chance that somewhere, someday, someone might reference a child
> > > object, I
> > > end up wasting a lot of memory and database labour.
> > >
> > >     As for long sessions being a bad idea; they *definitely* have
> > > their
> > > risks, especially if you aren't careful about evicting things when
> > > they
> > > aren't needed anymore. For web applications though, they really
> > > seem like
> > > the only practical approach in my experience. The threadlocal
> > > pattern can't
> > > solve the initialization problem, and the session-per-transaction
> > > pattern
> > > has performance problems *and* the lazy initialization problem.
> > >
> > >     I really think the whole "we refuse to automatically reconnect to
> > > lazy-load a connection and instead insist on throwing and
> > > exception" is
> > > database-purist-arrogance on the part of the Hibernate team. Most
> > > of their
> > > library is great, but this behavior is just *not* web friendly, and
> > > their
> > > smug assurance that it's "not a big deal to workaround" turns out
> > > not to be
> > > true in practice.
> > >
> > >     --- Pat
> > >
> > >
> > >> -----Original Message-----
> > >> From: Tomáš Drenčák [mailto:[EMAIL PROTECTED]
> > >> Sent: Tuesday, August 30, 2005 2:16 PM
> > >> To: Tapestry users
> > >> Subject: Re: Transaction handling. Where?
> > >>
> > >> You can initialize collections with Hibernate.initialize(collection),
> > >> or in query with left join fetch and than use detached objects in
> > >> further requests. And btw I've read that long open sessions aren't
> > >> good idea at all...
> > >>
> > >> 2005/8/30, Patrick Casey <[EMAIL PROTECTED]>:
> > >>
> > >>>
> > >>>        As I understand it though, with this approach the session
> > >>> has a
> > >>> lifespan that doesn't span multiple requests (in fact, its
> > >>> granularity
> > >>>
> > >> is <
> > >>
> > >>> 1 request). This raises problems in practice with use cases like:
> > >>>
> > >>>        User has a set of roles (lazy collection)
> > >>>
> > >>>        I bring up the User page. It loads from Session #1 which
> > >>> is then
> > >>> closed.
> > >>>        I click on the "show roles" button. We go back to Tapestry
> > >>> which
> > >>> merrily does a user.getRoles().iterator() and promptly blows up
> > >>> with a
> > >>>
> > >> lazy
> > >>
> > >>> initialization exception because Session #1 (the one which
> > >>> produced the
> > >>> user) no longer exists.
> > >>>
> > >>>        That and creating a fresh session for each database
> > >>> interaction,
> > >>> while not quite as bad a plan as creating a new JDBC connection
> > >>> for each
> > >>> query, is still not a great performance idea :(.
> > >>>
> > >>>        --- Pat
> > >>>
> > >>>
> > >>>> -----Original Message-----
> > >>>> From: Tomáš Drenčák [mailto:[EMAIL PROTECTED]
> > >>>> Sent: Tuesday, August 30, 2005 1:58 PM
> > >>>> To: Tapestry users
> > >>>> Subject: Re: Transaction handling. Where?
> > >>>>
> > >>>> I use classes described in
> > >>>>
> > >>>>
> > >> http://www.theserverside.com/articles/content/HivemindBuzz/
> > >> article.html.
> > >>
> > >>>> This is perfect approach for DAO pattern. Just declare DAO
> > >>>> object as
> > >>>> service with implementation and property of type
> > >>>> org.hibernate.Session
> > >>>> and setter setSession(Session). Session is then created uppon your
> > >>>> request to service and always initialized and closed through
> > >>>> ApplicationServlet which cleanups hivemind. There's also
> > >>>> transaction
> > >>>> interceptor...
> > >>>>
> > >>>> 2005/8/30, Chris Chiappone <[EMAIL PROTECTED]>:
> > >>>>
> > >>>>> Thanks, if I were to use this helperclass would I still go about
> > >>>>> getting the session before a save or update and closing the
> > >>>>> session
> > >>>>> after complete, as i was before?
> > >>>>>
> > >>>>> Also have you thought about using something like HiveTrans to do
> > >>>>>
> > >> this
> > >>
> > >>>>> for you?  I have been thinking about moving to tap 4 and using
> > >>>>> hivemind with hivetrans to deal with the hibernate session
> > >>>>>
> > >> management.
> > >>
> > >>>>>  Any thoughts??
> > >>>>>
> > >>>>> On 8/30/05, Patrick Casey <[EMAIL PROTECTED]> wrote:
> > >>>>>
> > >>>>>>
> > >>>>>>        To be honest, I *haven't* completely gotten around this
> > >>>>>>
> > >>>> problem.
> > >>>>
> > >>>>>> I've *sort of* gotten around it by going to a long-session
> > >>>>>> pattern
> > >>>>>>
> > >> so
> > >>
> > >>>> that
> > >>>>
> > >>>>>> the Hibernate session virtually never flushes. If you want though
> > >>>>>>
> > >> I'll
> > >>
> > >>>>>> attach my HibHelper class so you can get a feel for what I did.
> > >>>>>>
> > >>>>>>        Honestly though, it's not a magic bullet and I'm still
> > >>>>>>
> > >>>> struggling to
> > >>>>
> > >>>>>> find one. Still, if it gets you partway there, you're welcome to
> > >>>>>>
> > >> use
> > >>
> > >>>> it,
> > >>>>
> > >>>>>> modify it, whatever.
> > >>>>>>
> > >>>>>>        To use it effectively you'll need a combination of the
> > >>>>>>
> > >>>> HibHelper
> > >>>>
> > >>>>>> class (above) and the subclassed engine I provided earlier which
> > >>>>>>
> > >>>> stores and
> > >>>>
> > >>>>>> retrieves the Hibernate session from the user session.
> > >>>>>>
> > >>>>>>        --- Pat
> > >>>>>>
> > >>>>>>
> > >>>>>>> -----Original Message-----
> > >>>>>>> From: Chris Chiappone [mailto:[EMAIL PROTECTED]
> > >>>>>>> Sent: Tuesday, August 30, 2005 1:40 PM
> > >>>>>>> To: Tapestry users
> > >>>>>>> Subject: Re: Transaction handling. Where?
> > >>>>>>>
> > >>>>>>> I was search back some threads and noticed your HibHelper class.
> > >>>>>>>
> > >> Is
> > >>
> > >>>>>>> that basically the way you've gotten around this problem,
> > >>>>>>>
> > >> HibHelper
> > >>
> > >>>>>>> and the Servlet class you wrote?
> > >>>>>>>
> > >>>>>>> On 8/30/05, Patrick Casey <[EMAIL PROTECTED]> wrote:
> > >>>>>>>
> > >>>>>>>>
> > >>>>>>>>        Not necessarily, but it depends on how you want your
> > >>>>>>>>
> > >> system
> > >>
> > >>>> to
> > >>>>
> > >>>>>>>> manage transactions. One area where Hibernate and Tapestry
> > >>>>>>>>
> > >> don't
> > >>
> > >>>> "play
> > >>>>
> > >>>>>>> nice"
> > >>>>>>>
> > >>>>>>>> is with data binding.
> > >>>>>>>>
> > >>>>>>>>        Let's say I have a "user" form that is bound to a
> > >>>>>>>>
> > >>>> persistent User
> > >>>>
> > >>>>>>>> object.
> > >>>>>>>>
> > >>>>>>>>        Form gets rendered and goes out.
> > >>>>>>>>        User does some stuff and presses save.
> > >>>>>>>>        Form comes in, rewinds, and delta is pushed through
> > >>>>>>>>
> > >> into
> > >>
> > >>>> "user"
> > >>>>
> > >>>>>>>> object.
> > >>>>>>>>        *** At this point the user object is flagged by
> > >>>>>>>>
> > >> Hibernate
> > >>
> > >>>> as
> > >>>>
> > >>>>>>> dirty.
> > >>>>>>>
> > >>>>>>>> The next time the session flushes, it'll write through to the
> > >>>>>>>>
> > >>>> database,
> > >>>>
> > >>>>>>>> whether or not you call saveOrUpdate()!
> > >>>>>>>>
> > >>>>>>>>        This is problematic if, for example, you want to cancel
> > >>>>>>>>
> > >> the
> > >>
> > >>>>>>> update
> > >>>>>>>
> > >>>>>>>> because of failed validations :(.
> > >>>>>>>>
> > >>>>>>>>        One approach that can help is to evict everything from
> > >>>>>>>>
> > >> the
> > >>
> > >>>>>>> session
> > >>>>>>>
> > >>>>>>>> on load so that it doesn't auto-flush. If you do this though,
> > >>>>>>>>
> > >> you
> > >>
> > >>>> will
> > >>>>
> > >>>>>>>> likely have lazy initialization problems later on.
> > >>>>>>>>
> > >>>>>>>>        Another approach is to not directly bind your page to
> > >>>>>>>>
> > >> your
> > >>
> > >>>>>>>> persistent object, but that adds a whole other level of work
> > >>>>>>>>
> > >> to
> > >>
> > >>>> the page
> > >>>>
> > >>>>>>>> class.
> > >>>>>>>>
> > >>>>>>>>        All in all, I have not been happy with the interaction
> > >>>>>>>>
> > >>>> between
> > >>>>
> > >>>>>>>> Hibernate and Tapestry. With a classic servlet engine it's not
> > >>>>>>>>
> > >> a
> > >>
> > >>>> biggy
> > >>>>
> > >>>>>>>> because you can just not push invalid updates into the
> > >>>>>>>>
> > >> persistent
> > >>
> > >>>>>>> object.
> > >>>>>>>
> > >>>>>>>> With Tapestry though, the (normally helpful) behavior of
> > >>>>>>>>
> > >> directly
> > >>
> > >>>>>>> binding
> > >>>>>>>
> > >>>>>>>> user updates into the underlying persistent object doesn't
> > >>>>>>>>
> > >> allow
> > >>
> > >>>> the
> > >>>>
> > >>>>>>>> programmer any control over when updates go through.
> > >>>>>>>>
> > >>>>>>>>        Basically it all comes down to Hibernate insisting that
> > >>>>>>>>
> > >> it
> > >>
> > >>>> knows
> > >>>>
> > >>>>>>>> better than the programmer when things ought to be saved to
> > >>>>>>>>
> > >> the DB
> > >>
> > >>>> :(.
> > >>>>
> > >>>>>>>>
> > >>>>>>>>        --- Pat
> > >>>>>>>>
> > >>>>>>>>
> > >>>>>>>>
> > >>>>>>>>> -----Original Message-----
> > >>>>>>>>> From: Chris Chiappone [mailto:[EMAIL PROTECTED]
> > >>>>>>>>> Sent: Tuesday, August 30, 2005 1:07 PM
> > >>>>>>>>> To: Tapestry users
> > >>>>>>>>> Subject: Re: Transaction handling. Where?
> > >>>>>>>>>
> > >>>>>>>>> In my DOA i do the following...
> > >>>>>>>>>
> > >>>>>>>>>         public void makePersistentUser(Users user)
> > >>>>>>>>>                         throws InfrastructureException {
> > >>>>>>>>>
> > >>>>>>>>>                 try {
> > >>>>>>>>>                         HibernateUtil.beginTransaction();
> > >>>>>>>>>
> > >>>>>>>>>
> > >>>> HibernateUtil.getSession().saveOrUpdate(user);
> > >>>>
> > >>>>>>>>>                         HibernateUtil.commitTransaction();
> > >>>>>>>>>                         HibernateUtil.closeSession();
> > >>>>>>>>>                 } catch (HibernateException ex) {
> > >>>>>>>>>                         throw new
> > >>>>>>>>>
> > >> InfrastructureException(ex);
> > >>
> > >>>>>>>>>                 }
> > >>>>>>>>>         }
> > >>>>>>>>>
> > >>>>>>>>> Is this the wrong way to do it??
> > >>>>>>>>>
> > >>>>>>>>> On 8/30/05, Patrick Casey <[EMAIL PROTECTED]> wrote:
> > >>>>>>>>>
> > >>>>>>>>>>
> > >>>>>>>>>>        Have you tried subclassing BaseEngine and doing
> > >>>>>>>>>>
> > >> your
> > >>
> > >>>>>>> transaction
> > >>>>>>>
> > >>>>>>>>>> management in cleanupAfterRequest() and setupForRequest()
> > >>>>>>>>>>
> > >> e.g.
> > >>
> > >>>>>>>>>>
> > >>>>>>>>>> public class CorinnaEngine extends BaseEngine {
> > >>>>>>>>>>        private static final long serialVersionUID =
> > >>>>>>>>>>
> > >>>>>>>>> 3257284742721648952L;
> > >>>>>>>>>
> > >>>>>>>>>>
> > >>>>>>>>>>        protected void cleanupAfterRequest(IRequestCycle
> > >>>>>>>>>>
> > >> cycle)
> > >>
> > >>>> {
> > >>>>
> > >>>>>>>>>>                HibHelper.cleanupSession();
> > >>>>>>>>>>
> > >>>>>>>>>>                super.cleanupAfterRequest(cycle);
> > >>>>>>>>>>        }
> > >>>>>>>>>>
> > >>>>>>>>>>        protected void setupForRequest(RequestContext
> > >>>>>>>>>>
> > >> context)
> > >>
> > >>>> {
> > >>>>
> > >>>>>>>>>>                HttpSession hs =
> > >>>>>>>>>>
> > >> MyServlet.getCurrentSession();
> > >>
> > >>>>>>>>>>                HibHelper.attachSession(hs);
> > >>>>>>>>>>                HibHelper.getSession();
> > >>>>>>>>>>                super.setupForRequest(context);
> > >>>>>>>>>>        }
> > >>>>>>>>>>
> > >>>>>>>>>>
> > >>>>>>>>>>
> > >>>>>>>>>> }
> > >>>>>>>>>>
> > >>>>>>>>>>
> > >>>>>>>>>>> -----Original Message-----
> > >>>>>>>>>>> From: Koka [mailto:[EMAIL PROTECTED]
> > >>>>>>>>>>> Sent: Tuesday, August 30, 2005 12:00 PM
> > >>>>>>>>>>> To: [email protected]
> > >>>>>>>>>>> Subject: Transaction handling. Where?
> > >>>>>>>>>>>
> > >>>>>>>>>>> Well, I have pages that allow to edit some database
> > >>>>>>>>>>>
> > >> data, so
> > >>
> > >>>> I
> > >>>>
> > >>>>>>> have
> > >>>>>>>
> > >>>>>>>>> easy
> > >>>>>>>>>
> > >>>>>>>>>>> solution to start transaction at
> > >>>>>>>>>>> public void pageBeginRender(PageEvent event)
> > >>>>>>>>>>> {
> > >>>>>>>>>>> if (event.getRequestCycle().isRewinding())
> > >>>>>>>>>>>
> > >>>>>>>>>>> // start transaction here
> > >>>>>>>>>>> }
> > >>>>>>>>>>>
> > >>>>>>>>>>> and at
> > >>>>>>>>>>> public void pageEndRender(PageEvent event)
> > >>>>>>>>>>> {
> > >>>>>>>>>>> if (event.getRequestCycle().isRewinding())
> > >>>>>>>>>>> {
> > >>>>>>>>>>> // Commit or rollback if errors found
> > >>>>>>>>>>>
> > >>>>>>>>>>> }
> > >>>>>>>>>>> }
> > >>>>>>>>>>>
> > >>>>>>>>>>> Hmm, it WORKS fine but, hmmm, page render and
> > >>>>>>>>>>>
> > >>>> transactions...,
> > >>>>
> > >>>>>>> agrrr
> > >>>>>>>
> > >>>>>>>>> sure
> > >>>>>>>>>
> > >>>>>>>>>>> there's some other place to handle things.So the
> > >>>>>>>>>>>
> > >> question is
> > >>
> > >>>> what
> > >>>>
> > >>>>>>> is
> > >>>>>>>
> > >>>>>>>>> the
> > >>>>>>>>>
> > >>>>>>>>>>> right place to start/end transaction in Tap4
> > >>>>>>>>>>> TYA
> > >>>>>>>>>>>
> > >>>>>>>>>>
> > >>>>>>>>>>
> > >>>>>>>>>>
> > >>>>>>>>>> ----------------------------------------------------------
> > >>>>>>>>>>
> > >> ----
> > >>
> > >>>> ------
> > >>>>
> > >>>>>>> -
> > >>>>>>>
> > >>>>>>>>>> To unsubscribe, e-mail: tapestry-user-
> > >>>>>>>>>>
> > >>>> [EMAIL PROTECTED]
> > >>>>
> > >>>>>>>>>> For additional commands, e-mail: tapestry-user-
> > >>>>>>>>>>
> > >>>>>>> [EMAIL PROTECTED]
> > >>>>>>>
> > >>>>>>>>>>
> > >>>>>>>>>>
> > >>>>>>>>>>
> > >>>>>>>>>
> > >>>>>>>>>
> > >>>>>>>>> --
> > >>>>>>>>> ~chris
> > >>>>>>>>>
> > >>>>>>>>> ------------------------------------------------------------
> > >>>>>>>>>
> > >> ----
> > >>
> > >>>> -----
> > >>>>
> > >>>>>>>>> To unsubscribe, e-mail: tapestry-user-
> > >>>>>>>>>
> > >>>> [EMAIL PROTECTED]
> > >>>>
> > >>>>>>>>> For additional commands, e-mail: tapestry-user-
> > >>>>>>>>>
> > >>>> [EMAIL PROTECTED]
> > >>>>
> > >>>>>>>>
> > >>>>>>>>
> > >>>>>>>>
> > >>>>>>>>
> > >>>>>>>> --------------------------------------------------------------
> > >>>>>>>>
> > >> ----
> > >>
> > >>>> ---
> > >>>>
> > >>>>>>>> To unsubscribe, e-mail: tapestry-user-
> > >>>>>>>>
> > >>>> [EMAIL PROTECTED]
> > >>>>
> > >>>>>>>> For additional commands, e-mail: tapestry-user-
> > >>>>>>>>
> > >>>> [EMAIL PROTECTED]
> > >>>>
> > >>>>>>>>
> > >>>>>>>>
> > >>>>>>>>
> > >>>>>>>
> > >>>>>>>
> > >>>>>>> --
> > >>>>>>> ~chris
> > >>>>>>>
> > >>>>>>> ----------------------------------------------------------------
> > >>>>>>>
> > >> ----
> > >>
> > >>>> -
> > >>>>
> > >>>>>>> To unsubscribe, e-mail: tapestry-user-
> > >>>>>>>
> > >> [EMAIL PROTECTED]
> > >>
> > >>>>>>> For additional commands, e-mail: tapestry-user-
> > >>>>>>>
> > >>>> [EMAIL PROTECTED]
> > >>>>
> > >>>>>>
> > >>>>>>
> > >>>>>>
> > >>>>>> -----------------------------------------------------------------
> > >>>>>> -
> > >>>>>>
> > >> ---
> > >>
> > >>>>>> To unsubscribe, e-mail: tapestry-user-
> > >>>>>>
> > >> [EMAIL PROTECTED]
> > >>
> > >>>>>> For additional commands, e-mail: tapestry-user-
> > >>>>>>
> > >> [EMAIL PROTECTED]
> > >>
> > >>>>>>
> > >>>>>>
> > >>>>>>
> > >>>>>>
> > >>>>>
> > >>>>>
> > >>>>> --
> > >>>>> ~chris
> > >>>>>
> > >>>>> ------------------------------------------------------------------
> > >>>>> --
> > >>>>>
> > >> -
> > >>
> > >>>>> To unsubscribe, e-mail: tapestry-user-
> > >>>>> [EMAIL PROTECTED]
> > >>>>> For additional commands, e-mail: tapestry-user-
> > >>>>>
> > >> [EMAIL PROTECTED]
> > >>
> > >>>>>
> > >>>>>
> > >>>>>
> > >>>>
> > >>>> -------------------------------------------------------------------
> > >>>> --
> > >>>> To unsubscribe, e-mail: tapestry-user-
> > >>>> [EMAIL PROTECTED]
> > >>>> For additional commands, e-mail: tapestry-user-
> > >>>> [EMAIL PROTECTED]
> > >>>>
> > >>>
> > >>>
> > >>>
> > >>>
> > >>> --------------------------------------------------------------------
> > >>> -
> > >>> To unsubscribe, e-mail: [EMAIL PROTECTED]
> > >>> For additional commands, e-mail: tapestry-user-
> > >>> [EMAIL PROTECTED]
> > >>>
> > >>>
> > >>>
> > >
> > >
> > >
> > > ---------------------------------------------------------------------
> > > To unsubscribe, e-mail: [EMAIL PROTECTED]
> > > For additional commands, e-mail: [EMAIL PROTECTED]
> > >
> > >
> > >
> >
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: [EMAIL PROTECTED]
> > For additional commands, e-mail: [EMAIL PROTECTED]
> 
> 
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [EMAIL PROTECTED]
> For additional commands, e-mail: [EMAIL PROTECTED]
> 
> 


-- 
~chris

Reply via email to