I've used AspectJ to do this. It works, but it's not the most efficient solution out there. We have all our entities implement an interface "Persistent", so the pointcut looks like:

   pointcut persistentUse(Persistent persistent):
call(java.util.Set+ Persistent+.get*()) && target(persistent) // call to persistent setter
       && within(com.vms..*) // in our code
&& !cflow(call(Persistent+.new(..)) && within(com.vms..*)); // ignore our constructors

   Object around(Persistent persistent) :persistentUse(persistent){
       persistent.associateWithCurrentSession();
       Set result = (Set)proceed(persistent);
       for (Iterator iter = result.iterator(); iter.hasNext();) {
           Persistent collectionElement = (Persistent) iter.next();
           if (collectionElement != null) {
               collectionElement.associateWithCurrentSession();
           }
       }
       return result;
   }

associateWithCurrentSession() is a method on the Persistent interface (multiple inheritance with AspectJ!) that detects if we have a current session. If we have one, it does a lock().

Good:
- We don't have to think about this 95% of the time and it just works

Bad:
- It's inefficient to call this on every collection getter
- Every so often, we get bit on the rare case where we call a setter method and forget to re-enlist. We could easily add setters to the pointcut, but that gets even more inefficient.
- Not tested on hibernate3 (works on hibernate2)

I'm really looking for a better way to do this and watching to see what James comes up with in the next version of tapernate.

-Steve

Daniel Tabuenca wrote:
So do you have some way of locking all objects to the new session on
the subsequent request? Is this automated in some way? My problem with
the session-per-request-with-detached-objects is that there needs to
be some way to easily identify and re-attach the set of objects that
will be used. I've found it easiest to just keep the session and
reconnect it to the database on the new request. The one problem with
this is if you conversation is long your session might grow too big
since things are not cleaned out of the session even if you
application does not hold any additional references. Maybe ideally it
would be to use some form of AOP to automatically lock objects to the
new session on demand. This seems like it'd be awfully useful, though
I'm not sure how feasible it is to implement.

On 11/4/06, Bill Holloway <[EMAIL PROTECTED]> wrote:
For the lazy loading, what about writing a custom servlet filter as
recommended in the hibernate docs, one that handles the session for
you?  Let it sit out there in front of Tapestry and manage the
sessions.  I'm leaning toward
session-per-request-with-detached-objects and letting optimistic
locking handle the concurrency issues.  I'm not so concerned about
that issue.

My real issue is with the lazy-loading.  We'll have objects with some
pretty hefty fields -- text and maybe blob types -- that I REALLY
don't want to have loaded if I don't have to.

Cheers,
Bill

On 11/4/06, James Carman <[EMAIL PROTECTED]> wrote:
> Bill,
>
> The lazy loading problem can't really be solved in a generalized way.
> But, Tapernate does a lot of work for you.  I wouldn't suggest using
> the property persistence strategies from Tapernate right now.  I'm
> working on a new version that will hopefully be more robust.  The main
> problem that I face is knowing exactly *how* to reattach the detached
> object to the session when a request comes in.  There are a few
> different scenarios and the problem is knowing which one you're in!
> Also, if you use merge or update, then your object's state will be
> persisted at the end of the request (assuming that you leave
> transaction-per-request on).  What if you don't really want the state
> persisted during that request (you're in the middle of a "wizard"
> perhaps)?  I think the way to go is to use the
> session-per-conversation pattern, but I'm trying to come up with a
> good way to specify conversation boundaries.  Also, should we support
> more than one conversation at a time (what if the user clicks to go to
> another part of your webapp from within your wizard)?  If so, how do
> the potentially orphaned conversations get cleaned up?    This is what
> causes me to loose sleep at night (yes, I need a life). :-)
>
>
>
> On 11/3/06, Bill Holloway <[EMAIL PROTECTED]> wrote:
> > I've seen recently some criticism of Tapestry in terms of using
> > Hibernate.  Problems with lazy loading.  I know Tapernate is out
> > there, but the docs are pretty thin.  I'm using the threadLocal
> > version of the much-documented HibernateUtil in a DAO layer.  Going
> > well.  What will Tapernate actually do for me?  Does it really solve
> > the lazy-loading problem?  Are there decent docs?
> >
> > I would HATE to have to abandon tapestry to work around performance
> > problems falling out of non-lazy-loading.
> >
> > Thanks,
> > Bill
> >
> > ---------------------------------------------------------------------
> > 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]
>
>


--
"Budgets are moral documents."

     -- Ann Richards

---------------------------------------------------------------------
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]

Reply via email to