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]

Reply via email to