Community
Participate
Working Groups
If a CDOObject is detached, it means eStore == null. Now look at CDOStoreEList implementation: there are getStore().<xxx> calls in almost every method. NPE's all around. Simon, could you tell me in which cases CDOStoreEList is used? I can't get to reproduce this bug... Only through CDOEditor.
Hi Victor, CDOStoreEList is used only when CDOObject (its container) is not transient. If the list is used when the eStore == null this means it is a problem.
Victor can you tell me what you are doing in the CDOEditor to reproduce it.
>> Victor can you tell me what you are doing in the CDOEditor to reproduce it. The store is used by a EMF RemoveCommand in CDOEditor. You can reproduce this bug by selecting a node and it's parent in the tree, and then deleting both at the same time. This creates a CompoundCommand, composed by 2 RemoveCommands. If the parent's remove command is executed before the childrens', the RemoveCommand of the children will fail, because it tries to remove the children from the parent, but eStore is null! I fixed it by adding NPE control in the CDOStoreEList methods, but I guess is not the way!
This is because RemoveCOmmand keep reference to list testcase to reproduce it. Order order1 = getModel1Factory().createOrder(); OrderDetail orderDetail = getModel1Factory().createOrderDetail(); order1.getOrderDetails().add(orderDetail); resource.getContents().add(order1); EList<OrderDetail> list = order1.getOrderDetails(); resource.getContents().remove(0); // remove object by index // EXCEPTION list.remove(orderDetail); transaction.commit();
Created attachment 115764 [details] Patch v1 Vic, can you try this!!
Hi Simon, thanks for this fast patching! The problem is solved for the case I exposed, but seems to persist in some other more complex cases. I'll try to reproduce it and let you know!
You mean you still have a NPE somewhere. Humm.. this is strange. CAn you post the stack trace of the problem to see if it is the same ? With which Command do you still have problem ? RemoveCommand ? Simon
(In reply to comment #7) > You mean you still have a NPE somewhere. > Humm.. this is strange. CAn you post the stack trace of the problem to see if > it is the same ? > With which Command do you still have problem ? RemoveCommand ? yes, still the same, but now the deletion is more complicated: I'm removing, like before, a parent and its child, but I'm also now removing the child of another parent now. A - B | | | C | * - D | E I select to remove E, D and C (A and B and left unselected for the removal). It causes an efect similar as the first test I provided. C references E. Haven't tried thoroughly, so I cannot assure what's going on. I'm a bit busy with something else now, but I'll investigate and let you know ASAP. Regards, ViK.
It is very strange that you still have the NullPointerException.. because CDOStoreEList doesn't exist anymore. WHen you have the chance.. please do put the stack trace ?
Simon, Is EMF 2.5 necessary for this patch? I'm using 2.4.1.
(In reply to comment #10) > Simon, > > Is EMF 2.5 necessary for this patch? > > I'm using 2.4.1. > Humm.. I used 2.5 I'm not sure if we absolutely need 2.5. In the close future yes... With the stack trace I think I can have an idea of the problem since it cannot be the same stack trace as before. Simon
Simon, sorry for the delay, been a it busy preparing a dedicated CDO server machine. > With the stack trace I think I can have an idea of the problem since it cannot be the same stack trace as before. Yes, you are right. The error happens in DeleteCommand again, when executing at doExecute() for (i = indices.length - 1; i >= 0; i--) { ownerList.remove(indices[i]); } The StackTrace: org.eclipse.emf.cdo.util.ObjectNotFoundException: Object OID12587 not found (temporary = false). at org.eclipse.emf.internal.cdo.util.FSMUtil.validate(FSMUtil.java:185) at org.eclipse.emf.internal.cdo.CDOTransactionImpl.getObject(CDOTransactionImpl.java:421) at org.eclipse.emf.internal.cdo.CDOViewImpl.convertIDToObject(CDOViewImpl.java:926) at org.eclipse.emf.internal.cdo.CDOStore.get(CDOStore.java:180) at org.eclipse.emf.internal.cdo.CDOObjectImpl.depopulateRevisionFeature(CDOObjectImpl.java:416) at org.eclipse.emf.internal.cdo.CDOObjectImpl.cdoInternalPostDetach(CDOObjectImpl.java:380) at org.eclipse.emf.internal.cdo.CDOStateMachine.detach(CDOStateMachine.java:236) at org.eclipse.emf.cdo.eresource.impl.CDOResourceImpl.detached(CDOResourceImpl.java:766) at org.eclipse.emf.internal.cdo.CDOObjectImpl.eBasicSetContainer(CDOObjectImpl.java:807) at org.eclipse.emf.ecore.impl.BasicEObjectImpl.eInverseRemove(BasicEObjectImpl.java:1438) at org.eclipse.emf.ecore.util.DelegatingEcoreEList.inverseRemove(DelegatingEcoreEList.java:434) at org.eclipse.emf.common.notify.impl.DelegatingNotifyingListImpl.remove(DelegatingNotifyingListImpl.java:701) at org.eclipse.emf.edit.command.RemoveCommand.doExecute(RemoveCommand.java:327) at org.eclipse.emf.edit.command.AbstractOverrideableCommand.execute(AbstractOverrideableCommand.java:131) at org.eclipse.emf.common.command.CompoundCommand.execute(CompoundCommand.java:267) at org.eclipse.emf.common.command.CompoundCommand.execute(CompoundCommand.java:267) at org.eclipse.emf.edit.command.DeleteCommand.execute(DeleteCommand.java:136) at org.eclipse.emf.common.command.BasicCommandStack.execute(BasicCommandStack.java:84) at org.eclipse.emf.edit.ui.action.CommandActionHandler.run(CommandActionHandler.java:92) at org.eclipse.ui.actions.BaseSelectionListenerAction.runWithEvent(BaseSelectionListenerAction.java:168) at org.eclipse.jface.action.ActionContributionItem.handleWidgetSelection(ActionContributionItem.java:583) at org.eclipse.jface.action.ActionContributionItem.access$2(ActionContributionItem.java:500) at org.eclipse.jface.action.ActionContributionItem$5.handleEvent(ActionContributionItem.java:411) at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84) at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1003) at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:3823) at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3422) at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.java:2382) at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:2346) at org.eclipse.ui.internal.Workbench.access$4(Workbench.java:2198) at org.eclipse.ui.internal.Workbench$5.run(Workbench.java:493) at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:288) at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:488) at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149) at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:113) at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:193) at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110) at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79) at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:386) at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:179) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:549) at org.eclipse.equinox.launcher.Main.basicRun(Main.java:504) at org.eclipse.equinox.launcher.Main.run(Main.java:1236) at org.eclipse.equinox.launcher.Main.main(Main.java:1212)
I don't know if it helps, but, according to this: A - B | | | C | * - D | E The object that caused the exception would be object "C". I'll keep searching a little more after luch :)
(In reply to comment #13) > I don't know if it helps, but, according to this: > > A - B > | | > | C > | > * - D > | > E > > > The object that caused the exception would be object "C". > I'll keep searching a little more after luch :) > Victor can you tell me which objects you are deleting ? and the order ? (Is it only C?) Also can you describe each relations A-B containment = ? , one-to-many ? A-D containment = ? , one-to-many ? D-E containment = ? , one-to-many ? B-C containment = ? , one-to-many ? Is A the resource ? Otherwise where it is ? It is when we detach "C" we have the exception or is it the object not found is C ? In the case where we have the exception when C is detached I would like to know to which object C is referring. Thank you!
I think it is a real dangling reference since the objects you try to access was already removed. But I think we should revisit the fact that an object isn't available when we remove it. I think until we commit the detached object should be available until we commit. Obvisouly you have case that objects still need to be accessible. What do you think ?
Created attachment 115825 [details] Patch v2 - with no testcase updated Vic test it. Detach object are still available until we commit.
Yay, It works!!! I think keeping detached objects should fix many other issues in GMF :) Thank you!
Created attachment 115828 [details] Patch v3 - Final Detached objects are still available except for object with state = NEW.
Maybe objects should be available only internally, not through the public API ... CDOView.getObject What do you think Eike ?
Created attachment 116162 [details] Patch v4 - ready to be committed Simon, I'm not sure about the question in your last comment...
Committed to HEAD
Fix available in CDO 2.0.0 I200811041537
Generally available.