Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 352977 - Dirty Objects of CDOTransaction with CDOSavepoint
Summary: Dirty Objects of CDOTransaction with CDOSavepoint
Status: CLOSED WORKSFORME
Alias: None
Product: EMF
Classification: Modeling
Component: cdo.core (show other bugs)
Version: 4.2   Edit
Hardware: PC Windows 7
: P3 normal (vote)
Target Milestone: ---   Edit
Assignee: Eike Stepper CLA
QA Contact: Eike Stepper CLA
URL:
Whiteboard:
Keywords:
Depends on: 312534
Blocks:
  Show dependency tree
 
Reported: 2011-07-25 04:22 EDT by Steve Monnier CLA
Modified: 2013-03-19 04:51 EDT (History)
3 users (show)

See Also:


Attachments
Fix v1 (incomplete) (7.12 KB, patch)
2011-07-27 09:52 EDT, Eike Stepper CLA
no flags Details | Diff
Patch v2 (still wrong) (7.96 KB, patch)
2011-07-28 03:19 EDT, Eike Stepper CLA
no flags Details | Diff
Workaround that needs method visibility change (1.57 KB, patch)
2011-10-25 06:05 EDT, Steve Monnier CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Steve Monnier CLA 2011-07-25 04:22:38 EDT
Build Identifier: 

Hello,

I have an issue with dirty objects of a CDOTransaction using CDOSavepoint. It seems to be caused by CDOTransactionImpl.getDirtyObjects() that calls lastSavepoint.getAllDirtyObjects();

Here is my situation :
I have a TransactionalEditingDomainListener that creates a CDOSavepoint on transactionClosed for undo management.

I have an issue with the following scenario :
- I edit a CDOObject but don't commit -> A CDOSavepoint is created with this CDOObject dirty
- I delete this same CDOObject -> A CDOSavepoint is created with this CDOObject detached
- I Commit
-> because CDOTransactionImpl.getDirtyObjects() calls lastSavepoint.getAllDirtyObjects(); that returns dirty objects of all CDOSavepoint (If I'm right) instead of getDirtyObjects, my object is both detached and dirty on commit, causing NPE later in CDOCommitContextImpl.collectLobs(CDOTransactionImpl.java:2578)


I have two stack traces for this issue:
 - The first one has message : Impossible to commit changes made on resource '*my_resource*'on the repository
org.eclipse.emf.cdo.util.CommitException: java.lang.NullPointerException
at org.eclipse.emf.internal.cdo.transaction.CDOTransactionImpl.commit(CDOTransactionImpl.java:1072)
at org.eclipse.emf.cdo.transaction.CDOPushTransaction.push(CDOPushTransaction.java:245)
at org.eclipse.emf.cdo.transaction.CDOPushTransaction.push(CDOPushTransaction.java:240)
...
my SavingPolicy
...
Caused by: java.lang.NullPointerException
at org.eclipse.emf.internal.cdo.transaction.CDOTransactionImpl$CDOCommitContextImpl.collectLobs(CDOTransactionImpl.java:2578)
at org.eclipse.emf.internal.cdo.transaction.CDOTransactionImpl$CDOCommitContextImpl.preCommit(CDOTransactionImpl.java:2570)
at org.eclipse.emf.internal.cdo.transaction.CDOTransactionImpl$CDOCommitContextImpl.preCommit(CDOTransactionImpl.java:2415)
at org.eclipse.emf.internal.cdo.transaction.CDOSingleTransactionStrategyImpl.commit(CDOSingleTransactionStrategyImpl.java:66)
at org.eclipse.emf.internal.cdo.transaction.CDOTransactionImpl.commit(CDOTransactionImpl.java:1058)

- The second stack trace is a warning with message : "Save Failed"
java.lang.IllegalStateException: Failing event ROLLBACK in state CLEAN for Car@OID9 (data=null)
at org.eclipse.net4j.util.fsm.FiniteStateMachine.process(FiniteStateMachine.java:153)
at org.eclipse.emf.internal.cdo.view.CDOStateMachine.rollback(CDOStateMachine.java:448)
at org.eclipse.emf.internal.cdo.transaction.CDOTransactionImpl.rollbackCompletely(CDOTransactionImpl.java:1174)
at org.eclipse.emf.internal.cdo.transaction.CDOTransactionImpl.handleRollback(CDOTransactionImpl.java:1369)
at org.eclipse.emf.internal.cdo.transaction.CDOSingleTransactionStrategyImpl.rollback(CDOSingleTransactionStrategyImpl.java:118)
at org.eclipse.emf.internal.cdo.transaction.CDOTransactionImpl.rollback(CDOTransactionImpl.java:1087)
...
My SavingPolicy

Thanks,
Steve

Reproducible: Always

Steps to Reproduce:
1. edit a CDOObject but don't commit -> A CDOSavepoint is created with this CDOObject dirty
2. delete this same CDOObject -> A CDOSavepoint is created with this CDOObject detached
3. Commit
Comment 1 Steve Monnier CLA 2011-07-27 04:52:32 EDT
When you will have a fix, I will be interested to have it on the 4.0.X maintenance version, if possible.

Thank you,
Steve
Comment 2 Eike Stepper CLA 2011-07-27 04:55:11 EDT
One step after the other ;-)
Comment 3 Steve Monnier CLA 2011-07-27 05:02:56 EDT
Of course :)
Comment 4 Eike Stepper CLA 2011-07-27 09:52:26 EDT
Created attachment 200450 [details]
Fix v1 (incomplete)

Seems to fix the problem but breaks rollback()
Comment 5 Eike Stepper CLA 2011-07-28 03:13:42 EDT
Committed revision 8836:
- trunk/plugins/org.eclipse.emf.cdo
Comment 6 Eike Stepper CLA 2011-07-28 03:14:41 EDT
Committed revision 8838:
- trunk/plugins/org.eclipse.emf.cdo
Comment 7 Eike Stepper CLA 2011-07-28 03:19:14 EDT
Created attachment 200494 [details]
Patch v2 (still wrong)

As also explained on bug 353167 savepoints are not in a very good shape with respect to detachment or reattachment and it's very hard to change. It seems that a major rework is pending and I'm a little reluctant to spend much effort on this old design. I'll come back to this bugzilla when the big redesign takes place. Sorry for the inconvenience!
Comment 8 Steve Monnier CLA 2011-10-25 06:05:28 EDT
Created attachment 205900 [details]
Workaround that needs method visibility change

I found a workaround by calling the collapseSavepoints method of the CDOTransactionImpl before calling SetSavepoint. However, collapseSavepoints method is private. Is it possible to have this method as API like in this patch. Is this workaround acceptable for 4.0_Maintenance branch?

Thanks
Comment 9 Eike Stepper CLA 2011-11-12 01:46:23 EST
Steve, your patch is against 4.0 while this bug is against 4.1. Generally we're trying to back-port bug fixes but changes to public interfaces are generally not allowed in maintenance streams. We could back-port the change to CDOTransactionImpl, though, and you'd have to down-cast your tx handle.

Out of curiosity, How do you mimic the CDOCommitContext needed when calling collapseSavepoints()?
Comment 10 Steve Monnier CLA 2011-11-14 05:34:23 EST
(In reply to comment #9)
> Steve, your patch is against 4.0 while this bug is against 4.1. 
Sorry my bad, I must have missed it during the creation of this issue.

>Generally we're
> trying to back-port bug fixes but changes to public interfaces are generally
> not allowed in maintenance streams. We could back-port the change to
> CDOTransactionImpl, though, and you'd have to down-cast your tx handle.
Ok, it's good for me.

> Out of curiosity, How do you mimic the CDOCommitContext needed when calling
> collapseSavepoints()?
Well, we are in a TransactionalEditingDomainListener that creates a
CDOSavepoint on transactionClosed for undo management. 
After initialization of this TransactionalEditingDomainListener, we create and
keep an InternalCDOCommitContext by calling
InternalCDOTransaction.createCommitContext();
This way, in transactionClosed(), if we are not dealing with a rollback, we can
collapseSavepoints before calling setSavepoint() on the CDOTransaction.
I hope it is not an heresy, but this workaround seems to work fine, in our case at least.
Comment 11 Eike Stepper CLA 2011-11-15 01:42:46 EST
Steve, this is at least dangerous because the constructor of CDOCommitContextImpl calls calculateCommitData() only once. The transaction is not supposed to be used between the commit context creation and the end of the commit operation.

Please note that Thales is currently considering to provide some budget for the general savepoint redesign I've mentioned in comment #7.
Comment 12 Eike Stepper CLA 2012-08-14 22:57:14 EDT
Moving all open issues to 4.2. Open bugs can be ported to 4.1 maintenance after they've been fixed in master.
Comment 13 Steve Monnier CLA 2013-02-19 09:22:40 EST
I can't reproduce the issue of the initial scenario on CDO 4.2. I guess you can close this one.
Comment 14 Eike Stepper CLA 2013-03-19 04:51:25 EDT
Ok. Thanks for letting me know ;-)