Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 310574 - CDOAddFeatureDelta with null value
Summary: CDOAddFeatureDelta with null value
Status: CLOSED FIXED
Alias: None
Product: EMF
Classification: Modeling
Component: cdo.core (show other bugs)
Version: 4.0   Edit
Hardware: PC Linux
: P3 normal (vote)
Target Milestone: ---   Edit
Assignee: Eike Stepper CLA
QA Contact: Eike Stepper CLA
URL:
Whiteboard: offline-02
Keywords:
Depends on:
Blocks: 306710
  Show dependency tree
 
Reported: 2010-04-27 04:14 EDT by Cyril Jaquier CLA
Modified: 2012-09-21 06:52 EDT (History)
6 users (show)

See Also:


Attachments
CDOAddFeatureDelta with null value and redundant CDOFeatureDeltas (3.84 KB, text/x-java)
2010-04-27 04:18 EDT, Cyril Jaquier CLA
no flags Details
Remove CDO[Add|Set]FeatureDelta from CDOListFeatureDelta instead of setting the value to CDOID.NULL (43.44 KB, patch)
2010-06-11 07:35 EDT, Cyril Jaquier CLA
no flags Details | Diff
Do not patch the indexes when removing a CDOSetFeatureDelta (5.77 KB, patch)
2010-10-13 08:58 EDT, Cyril Jaquier CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Cyril Jaquier CLA 2010-04-27 04:14:25 EDT
Build Identifier: 

In a test case I have the following code:

data1.getHeartbeatMap().put("AAR1", heartbeat);
data1.getHeartbeatMap().remove("AAR1");
commit();

CDO generates the following feature deltas:

[CDORevisionDelta[ScenarioData@OID298:0v1 --> [CDOFeatureDelta[heartbeatMap, LIST, list=[CDOFeatureDelta[heartbeatMap, ADD, value=NULL, index=0], CDOFeatureDelta[heartbeatMap, REMOVE, value=UNKNOWN, index=0]]]]]]

Notice the "value=NULL" for the ADD. Is this a bug in CDO or the expected behaviour? I think (I've not tested) that in this case, 2 notifications whould be generated, one ADD with null and one REMOVE. I would have expected either ADD with a value (e.g. heartbeat in this case) or no notification at all.

Moreover, when doing this:

data1.getHeartbeatMap().put("AAR1", heartbeat);
data1.getHeartbeatMap().remove("AAR1");
data1.getHeartbeatMap().put("AAR1", heartbeat);
data1.getHeartbeatMap().remove("AAR1");
data1.getHeartbeatMap().put("AAR1", heartbeat);
data1.getHeartbeatMap().remove("AAR1");
data1.getHeartbeatMap().put("AAR1", heartbeat);
data1.getHeartbeatMap().remove("AAR1");
data1.getHeartbeatMap().put("AAR1", heartbeat);
data1.getHeartbeatMap().remove("AAR1");
data1.getHeartbeatMap().put("AAR1", heartbeat);
data1.getHeartbeatMap().remove("AAR1");
commit();

CDO generates the following feature deltas:

[CDORevisionDelta[ScenarioData@OID1586:0v1 --> [CDOFeatureDelta[heartbeatMap, LIST, list=[CDOFeatureDelta[heartbeatMap, ADD, value=NULL, index=0], CDOFeatureDelta[heartbeatMap, REMOVE, value=UNKNOWN, index=0], CDOFeatureDelta[heartbeatMap, ADD, value=NULL, index=0], CDOFeatureDelta[heartbeatMap, REMOVE, value=UNKNOWN, index=0], CDOFeatureDelta[heartbeatMap, ADD, value=NULL, index=0], CDOFeatureDelta[heartbeatMap, REMOVE, value=UNKNOWN, index=0], CDOFeatureDelta[heartbeatMap, ADD, value=NULL, index=0], CDOFeatureDelta[heartbeatMap, REMOVE, value=UNKNOWN, index=0], CDOFeatureDelta[heartbeatMap, ADD, value=NULL, index=0], CDOFeatureDelta[heartbeatMap, REMOVE, value=UNKNOWN, index=0], CDOFeatureDelta[heartbeatMap, ADD, value=NULL, index=0], CDOFeatureDelta[heartbeatMap, REMOVE, value=UNKNOWN, index=0]]]]]]

Can't CDO optimize this? How is this handled at the database level? 

Reproducible: Always
Comment 1 Cyril Jaquier CLA 2010-04-27 04:18:59 EDT
Created attachment 166164 [details]
CDOAddFeatureDelta with null value and redundant CDOFeatureDeltas
Comment 2 Cyril Jaquier CLA 2010-04-27 04:20:06 EDT
(In reply to comment #1)
> Created an attachment (id=166164) [details]
> CDOAddFeatureDelta with null value and redundant CDOFeatureDeltas

This is a test case that reproduce the issue.
Comment 3 Cyril Jaquier CLA 2010-05-28 02:50:17 EDT
The NULL value in the CDOAddFeatureDelta is caused by:

cachedSources[i].clear();

in CDOListFeatureDeltaImpl.cleanupWithNewDelta(CDOFeatureDelta). This happens when the CDORemoveFeatureDelta is added to the CDOListFeatureDelta.

What is the purpose of CDOListFeatureDeltaImpl.cleanupWithNewDelta(CDOFeatureDelta)?
Comment 4 Eike Stepper CLA 2010-05-28 05:24:51 EDT
Unfortunately I have no clue at the moment. IIRC all this has been added by Simon (CC'ed). Simon has been very quiet in the recent past. If he doesn't see this question I'll try to forward it via email. Or we'll have to find out without his help ;-(
Comment 5 Cyril Jaquier CLA 2010-05-28 09:34:11 EDT
The explanation is here: https://bugs.eclipse.org/bugs/show_bug.cgi?id=250757#c3

It seems however that data binding (and others) does not really like this null value.

!ENTRY org.eclipse.core.databinding 4 0 2010-05-28 15:18:37.462
!MESSAGE Unhandled exception: null argument:element cannot be null
!STACK 0
org.eclipse.core.runtime.AssertionFailedException: null argument:element cannot be null
	at org.eclipse.core.runtime.Assert.isNotNull(Assert.java:85)
	at org.eclipse.jface.internal.databinding.viewers.ObservableCollectionTreeContentProvider$TreeNode.<init>(ObservableCollectionTreeContentProvider.java:410)
	at org.eclipse.jface.internal.databinding.viewers.ObservableCollectionTreeContentProvider.getOrCreateNode(ObservableCollectionTreeContentProvider.java:243)
	at org.eclipse.jface.internal.databinding.viewers.ObservableCollectionTreeContentProvider.getOrCreateNode(ObservableCollectionTreeContentProvider.java:237)
	at org.eclipse.jface.databinding.viewers.ObservableListTreeContentProvider$Impl.access$5(ObservableListTreeContentProvider.java:1)
	at org.eclipse.jface.databinding.viewers.ObservableListTreeContentProvider$Impl$ListChangeListener.handleListChange(ObservableListTreeContentProvider.java:114)
	at org.eclipse.core.databinding.observable.list.ListChangeEvent.dispatch(ListChangeEvent.java:61)
	at org.eclipse.core.databinding.observable.ChangeManager.fireEvent(ChangeManager.java:119)
	at org.eclipse.core.databinding.observable.list.DecoratingObservableList.fireListChange(DecoratingObservableList.java:59)
	at org.eclipse.core.databinding.observable.list.DecoratingObservableList.handleListChange(DecoratingObservableList.java:97)
	at org.eclipse.core.databinding.observable.list.DecoratingObservableList$1.handleListChange(DecoratingObservableList.java:71)
	at org.eclipse.core.databinding.observable.list.ListChangeEvent.dispatch(ListChangeEvent.java:61)
	at org.eclipse.core.databinding.observable.ChangeManager.fireEvent(ChangeManager.java:119)
	...

Are there any means to detect that the CDOAddFeatureDelta value has been "artificially" set to null?
Comment 6 Thomas Kowatsch CLA 2010-05-31 12:27:57 EDT
I can confirn Cyril's statement in comment 5.

Databinding has real problem when notifications have null values (e.g. added value is null or old value of removed object is null). The whole databinding chain will break and the UI will not display the current status correctly.

See also https://bugs.eclipse.org/bugs/show_bug.cgi?id=303868
Comment 7 Cyril Jaquier CLA 2010-06-04 07:41:56 EDT
I'm working on this issue.
Comment 8 Eike Stepper CLA 2010-06-04 07:44:31 EDT
Thank you, Cyril. Let me know if I can help!
Comment 9 Cyril Jaquier CLA 2010-06-08 09:44:09 EDT
I tried to modify CDOListFeatureDeltaImpl so as to completely remove the ADD/REMOVE deltas from the list instead of setting the value to CDOID.NULL. But CDOListFeatureDelta may also contain CDOMoveFeatureDelta which makes the whole thing a lot more complicated (patch the indexes).

Are ADD, REMOVE and MOVE the only feature deltas that may be added to a CDOListFeatureDelta?

Eike, do you think that "optimizing" the CDOListFeatureDelta's feature list (by removing/modifying the feature deltas) is the right solution? This would solve the ADD with value=NULL issue and decrease the number of notifications, DB accesses, etc at the same time.

Do you see a better solution?
Comment 10 Pascal Lehmann CLA 2010-06-08 09:55:08 EDT
(In reply to comment #9)
> I tried to modify CDOListFeatureDeltaImpl so as to completely remove the
> ADD/REMOVE deltas from the list instead of setting the value to CDOID.NULL. But
> CDOListFeatureDelta may also contain CDOMoveFeatureDelta which makes the whole
> thing a lot more complicated (patch the indexes).
We can talk about this tomorrow, I had to do this a couple of times already ;)

> Are ADD, REMOVE and MOVE the only feature deltas that may be added to a
> CDOListFeatureDelta?
Afaik CLEAR will be the 4th list feature delta which can occur.

> Eike, do you think that "optimizing" the CDOListFeatureDelta's feature list (by
> removing/modifying the feature deltas) is the right solution? This would solve
> the ADD with value=NULL issue and decrease the number of notifications, DB
> accesses, etc at the same time.
It would also solve the IndexOutOfBoundsException in the latest testcase patch for bug #306710
Comment 11 Cyril Jaquier CLA 2010-06-08 10:05:15 EDT
(In reply to comment #10)
> (In reply to comment #9)
> > I tried to modify CDOListFeatureDeltaImpl so as to completely remove the
> > ADD/REMOVE deltas from the list instead of setting the value to CDOID.NULL. But
> > CDOListFeatureDelta may also contain CDOMoveFeatureDelta which makes the whole
> > thing a lot more complicated (patch the indexes).
> We can talk about this tomorrow, I had to do this a couple of times already ;)
> 

Good idea ;-)

> > Are ADD, REMOVE and MOVE the only feature deltas that may be added to a
> > CDOListFeatureDelta?
> Afaik CLEAR will be the 4th list feature delta which can occur.
> 

Indeed CLEAR may be added to LIST. But it's not really a problem because CLEAR clears the feature delta list before being added to CDOListFeatureDelta. In CDORevisionDeltaImpl:

// Remove all previous changes
if (delta instanceof CDOClearFeatureDelta || delta instanceof CDOUnsetFeatureDelta)
{
  listDelta.getListChanges().clear();
}

listDelta.add(delta);
Comment 12 Eike Stepper CLA 2010-06-08 10:09:22 EDT
(In reply to comment #10)
> We can talk about this tomorrow, I had to do this a couple of times already ;)

So far all your assumption here looked correct. Maybe we can have a conf call altogether tomorrow.
Comment 13 Cyril Jaquier CLA 2010-06-11 07:35:29 EDT
Created attachment 171708 [details]
Remove CDO[Add|Set]FeatureDelta from CDOListFeatureDelta instead of setting the value to CDOID.NULL
Comment 14 Cyril Jaquier CLA 2010-06-11 07:43:52 EDT
Out of the 4265 tests, one "randomly" gives an error [1] but I don't think it is related to this patch. If I run the test alone, it works. Probably a concurrency/timing issue.

The patch removes the CDOAddFeatureDelta (or CDOSetFeatureDelta) from the CDOListFeatureDelta when a corresponding CDORemoveFeatureDelta is added. CDOFeatureDelta in the list are patched (or removed) if needed/possible during the process.

1) The number of lines that you added/changed is smaller than 250.
Without comments and tests yes. With them I would say no. So feel free to remove the comments :-D

2) You are the only author of these changed lines.
Yes with the help of Pascal Lehmann

3) You apply the EPL to these changed lines.
Yes

Hope I did not mess up too many things ;-)

[1] BranchingTest.testDetachExisting [Combined, MEMBranches, JVM, Legacy]
Comment 15 Eike Stepper CLA 2010-06-15 04:13:01 EDT
Committed to HEAD
Comment 16 Eike Stepper CLA 2010-06-29 04:36:42 EDT
Available in 3.0 GA:
http://download.eclipse.org/modeling/emf/cdo/updates/3.0-releases/
Comment 17 Cyril Jaquier CLA 2010-10-13 08:53:18 EDT
The committed fix is not 100% right and fails in certain cases that involve CDOSetFeatureDelta.

Currently, when removing CDOSetFeatureDelta, the indexes of the other feature deltas are patched. This should not be the case because CDOSetFeatureDelta does not modify the length of the list.
Comment 18 Cyril Jaquier CLA 2010-10-13 08:58:58 EDT
Created attachment 180763 [details]
Do not patch the indexes when removing a CDOSetFeatureDelta

This patch also contains a fix to CDOLegacyWrapper (find out the right index instead of using 0) and a test case.

1) The number of lines that you added/changed is smaller than 250.
Yes

2) You are the only author of these changed lines.
Yes

3) You apply the EPL to these changed lines.
Yes
Comment 19 Eike Stepper CLA 2010-10-16 02:21:53 EDT
Martin, here is a small change to CDOLegacyWrapper. Does it conflict with your fix in bug 327604?
Comment 20 Eike Stepper CLA 2010-10-16 02:35:12 EDT
Good catch, Cyril. THan k you ;-)

Committed to HEAD
Comment 21 Eike Stepper CLA 2011-06-23 04:27:55 EDT
Moving all open problem reports to 4.0
Comment 22 Eike Stepper CLA 2012-09-21 06:52:37 EDT
Closing.