em.merge(treeOfEntities) impossible with optimistic locking [message #1043287] |
Wed, 17 April 2013 14:07 |
Markus KARG Messages: 28 Registered: June 2011 |
Junior Member |
|
|
We never thought too much about it, but today we noticed a Situation which is really bad, and we'd like to discuss how to most simply work around it!
Situation:
There is a tree of entities, where root node A and leaf nodes B and C all use optimistic locking (integer version).
Initial Tree:
A (v1)
!
+-- B (v1)
!
+-- C (v1)
As it is a "parent-child" kind of relation, all operations on A are cascaded to B and C.
Now, two processes concurrently perform different transactions on separate leafs of the tree:
TX 1:
em.detach(A)
B.setX(...)
em.merge(A) // Works well
A (v1)
!
+-- B' (v2)
!
+-- C (v1)
At the same time, process 2 does this:
TX 2:
em.detach(A)
C.setX(...)
em.merge(A) // Throws OptimisticLockException!
A (v1)
!
+-- B (v1)
!
+-- C' (v2)
The result of TX 2 is OptimisticLockException, as EclipseLink assumes that B1 shall be nodified back to v1 again -- what actually is not wanted by the user. In fact, B was neither touched by TX 2, nor A was!
Expected result from a user's point of view instead shall be:
A (v1)
!
+-- B' (v2)
!
+-- C' (v2)
What we are desperately seeking is a solution how to tell EclipseLink that TX 2 actually is NOT wanting to restore B back to v1, but that B shall simply get ignored, as it was not touched at all!
Any help appreciated!
Thanks!
-Markus
|
|
|
Re: em.merge(treeOfEntities) impossible with optimistic locking [message #1044706 is a reply to message #1043287] |
Fri, 19 April 2013 08:28 |
Markus KARG Messages: 28 Registered: June 2011 |
Junior Member |
|
|
As Oracle's Tom WARE told me, this is definitively not a bug in EclipseLink, but it is in fact impossible for any JPA Provider to guess whether B(v1) sent together with the second merge is meant as a replacement ("undo") for the previously merged B'(v2), or whether it is simply untouched. Sounds reasonable, unfortunately. While SVN or GIT have a history to decide this, JPA has not.
So the question is: How to work around this?
One idea would be to store a dirty flag with A, B and C if changed, and then just before the merge happens, replace B(v1) by em.find(B.class, B.id). I assume this will work as it effectively leads to the fact that EclipseLink now knows that B is simply untouched. But on the other hand that means that the client must track changes, which I hoped he wouldn't. Think of People using a text editor to modify XML. This idea would impose the burden to manually tell each changed node. While technically reasonable, it will sound ridiculous to the user.
Any other ideas appreciated!
Regards
-Markus
|
|
|
Re: em.merge(treeOfEntities) impossible with optimistic locking [message #1047679 is a reply to message #1044706] |
Tue, 23 April 2013 14:09 |
|
Yes, if you call merge() on an object, it will be merged, not just changes (which are not known).
If you have a stateful model, you can create your EntityManager at the start of the user's interaction, such that you query the original through the EntityManager and return it to the user. Then when you merge the object back from the user, the persistence context will have the original object and only merge and update what was changed.
James : Wiki : Book : Blog : Twitter
|
|
|
|
Powered by
FUDForum. Page generated in 0.03225 seconds