Why don't you use EJB SessionBeans with TransactionManagement BEAN, and inject (@EJB) this session bean in session scoped managed bean. This way you can preserve transaction along multiple requests. And yes, use Eclipselink (it has lazy loading ;) ).

On 07/02/2010 08:07 PM, Mike Kienenberger wrote:
I am not familiar with orchestra, so I can't comment there.   It has
not been an option for us up to this point.

However, if you leave a transaction active after a response, it's
always going to be an issue no matter what framework you use.

For us, the problem with holder objects is the deep hierarchy of
entities and relationships we have.   We have probably close to a
thousand entities right now, and most multiple-request-spanning
transactions deal with very complex, deep, and width relationship
paths.   They only work well in the simple cases where we don't need
them.

On Fri, Jul 2, 2010 at 3:39 AM, Werner Punz<werner.p...@gmail.com>  wrote:
Mike you left out the obvious one, simply use a conversation framework.
The problem is not transactions but it is that the entity manger is dropped
along the way hence silently detaching all objects and running you into
detached error hell. (You still can either setup your jpa provider so that
lazy loading can happen outside of transaction barriers or prefetch
everything via fetch join)

I personally found as soon as you go to a conversation framework things
become way easier (although not entirely easy)

Also what was the problem with holder objects. I personally am thinking of
moving that way especially since JPA allows to map it transparently via
queries like following select new FakeHolder(entity.id, entity....) from
EntityClass entity).

The downside is that you need more logic for pushing the data back into the
entity objects before writing. But the fake holder pattern is exactly what
iBatis enforces (although it has the write back logic pushed into the
configuration) and it works out well in a web centric szenario.


WErner


Am 01.07.10 23:54, schrieb Mike Kienenberger:
I am, sort of.

You really can't leave the transaction open beyond the request
response as it may never complete.

Some of the ways you can deal with it are:

1) work with fake holder entities that get changed back into real
entities at the final commit.   Very ugly -- tried this one at first,
but I don't use it anymore.

2) Work with detached objects.  Reattach them back right before the
final commit.   This is what I currently do.    I basically invented a
Unit-Of-Work framework that runs over the top of JPA.    The unit of
work has a separate persistence manager that loads an object, then
immediately detaches it.   Our framework requires each object to call
save() to commit changes.   When in the UoW, all save does is add the
object to a change-tracker (inserts, deletes, updates).    Then when
the UoW is committed, the objects are persisted or merged, then
committed all in one method call.

But in all honesty, this approach also has caused us a lot of hassles.
   We are most likely going to dump JPA and replace it with Apache
Cayenne, which uses a real unit of work concept.

Another option for you might be to use an implementation-specific unit
of work provided by your JPA implementation.   However, I don't know
if you might have other issues.   I used Cayenne before I used JPA,
and I know Cayenne does exactly what I need.

A third option you could consider if you want to risk leaving the
transaction open.

a) Catch the window onunload event, and mixed with ajax, send an ajax
request when the user improperly attempts to leave the page (closes
the window or browser, enters a url directly, back buttons, some other
non-transaction-friendly link clicked).

I got this far with that approach, but didn't pursue it.  Note that
this can only detect when the user is about to leave the page.  It
cannot do anything at that point -- you'd have to do something about
it in some other way.

                  window.onbeforeunload = confirmExit;
                  function confirmExit()
                  {
                    if (needToConfirm)
                      return "You have attempted to leave this page.  If
you have
made any changes to the fields without clicking the Save button, your
changes will be lost.  Are you sure you want to exit this page?";
                  }


b) Some other kind of client-side state tracking so that you know when
the user has navigated away from the current multi-request task.
We're sticking a taskGroupIdentifier field on every form (ajax
included) so we know when the user does something to switch to a new
task than the one we're currently working with.  Doesn't help if you
have some transaction left open and the user never hits the web server
again, but a timeout could deal with that.


In short, I think it's a difficult problem, and I think JPA is
incapable of dealing with it correctly.   The other shortfall we have
is that JPA cannot rollback a transaction.   You have no way of
knowing what state your application is in once you roll back the
transaction.   Again Cayenne automatically puts everything exactly
where it was at the start of your unit of work if you do a rollback.

On Thu, Jul 1, 2010 at 9:53 AM, Bruno Aranda<brunoara...@gmail.com>
  wrote:
Hi,

Is anyone here using long JPA transactions in their applications
(transactions that span more than one request) but not using Orchestra?.
How
are you doing it?

Cheers,

Bruno



Reply via email to