openjpa-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From David Van Couvering <da...@vancouvering.com>
Subject Help requested around rollback semantics
Date Thu, 19 Apr 2007 23:40:57 GMT
Hi, all.  I am hoping you can help me out here.  You don't have a users 
list so I'm sending it to dev.

I've been implementing some code against JPA and I was trying to figure 
out how to handle a transaction rollback. I wasn't sure if JPA is 
responsible for rolling back the state of any objects in the persistence 
context.

The answer appears to be no, and I found this in the spec:

===
3.3.2 Transaction Rollback

For both transaction-scoped and extended persistence contexts, 
transaction rollback causes all pre-existing managed instances and 
removed instances[15] to become detached. The instances’ state will be 
the state of the instances at the point at which the transaction was 
rolled back. Transaction rollback typically causes the persistence 
context to be in an inconsistent state at the point of rollback. In 
particular, the state of version attributes and generated state (e.g., 
generated primary keys) may be inconsistent. Instances that were 
formerly managed by the persistence context (including new instances 
that were made persistent in that transaction) may therefore not be 
reusable in the same manner as other detached objects—for example, they 
may fail when passed to the merge operation.
====

As an app writer, this statement is somewhat disconcerting.

I was wondering if there is any guidance available for how I can write 
an app against JPA that handles rollback correctly.

I'm writing a controller that interacts with entity objects, passing 
them around to various methods, storing them in member variables, and so 
on. I don't want to detach them, because (a) it is costly for me to copy 
all the data into a separate, detached instance, and then during the 
merge operation to have them copied back into the instance stored in the 
persistence context and (b) I never know if I can access a field or 
relationship because I don't know if the field or related instance has 
been loaded yet. When I keep them attached, JPA takes care of this for me.

Then let's say I perform a persist() operation and it fails and rolls 
back. This means all my objects I've been passing around and storing in 
various places are suddenly detached and "may be" in an inconsistent 
state (which from the perspective of a program is the same as saying 
they *are* in an inconsistent state), and thus are invalid.

So now what do I do? Is there a recommended approach for dealing with 
this? How does my application detect this in some global way, and 
reloads from the persistence context all the instances it was keeping 
around?

The other concern I have is I'd like consumers of my controller to use 
entity objects as POJOs without having to know or care if they are 
entities. But the rollback semantics means my callers have to deal with 
handling a rollback. Alternately I could pay the copy cost of detaching 
my objects before passing them up to higher levels, but then my caller 
will still have to deal with the semantics of detached objects (e.g. 
lazy fields or associated instances may be null). I don't see any way to 
expose entities directly to higher levels of my app that are 
entity-unaware... Which means I have to wrap my entities into proxy 
classes that handle all the JPA semantics internally and don't expose 
this to the caller.

I am concerned that the rollback consequences can slip past developers, 
who will then build apps that behave very erratically after a 
transaction rollback. I know it's in the spec, but having worked with 
lots of developers, most of them don't read the spec, but instead 
cut-and-paste from examples. It would be great if we did a blog about 
this, and provided some code showing how to do it right... I could do 
this, but before I do I thought I'd check with you all first for any 
thoughts you have on this.

Thanks!

David

Mime
View raw message