Home » Modeling » EMF » [CDO] Strange Commit Problem with URI Clash
|[CDO] Strange Commit Problem with URI Clash [message #1729185]
||Mon, 11 April 2016 21:36
| Thorsten Schlathölter
Registered: February 2012
I have a large model (approx. 140000 Objects) which I am trying to commit into a CDO repository. The model is separated into different Resources. The model is committed into the repository and new idMappings are generated and returned to the client.
Now in the postCommit Method of CDOTransactionImpl objects are commited via CDOStateMachine:
private void postCommit(Map<CDOID, CDOObject> objects, CommitTransactionResult result)
for (CDOObject object : objects.values())
if I look into the Collection of values i see the following entries at the respective positions. I am not sure about the ordering in the collection but it is obvious that the ordering is close to but not exactly the ordering in which the objects were attached to the transaction as can be seen by the oid identifier. The oid which can be seen is still the temporary id which was assigned on the client side:
Now the problem is the entry on position 100525. The ContainerMetaData object is actually contained in the CDOResource on position 100526. Note that it is processed before it's CDOResource. While it is being processed by the StateMachine a CDOModificationTrackingAdapter comes along and checks if the ContainerMetaData object is contained:
CDOTransactionImpl(AbstractCDOView).newResourceInstance(InternalCDORevision) line: 1866
CDOTransactionImpl(AbstractCDOView).createObject(CDOID) line: 1833
CDOTransactionImpl(AbstractCDOView).getObject(CDOID, boolean) line: 1655
CDOTransactionImpl.getObject(CDOID, boolean) line: 1494
CDOTransactionImpl(AbstractCDOView).convertIDToObject(Object) line: 2122
CDOStoreImpl.convertIDToObject(InternalCDOView, EObject, EStructuralFeature, int, Object) line: 897
CDOStoreImpl.getResource(InternalEObject) line: 161
ContainerMetaDataImpl(CDOObjectImpl).eDirectResource() line: 605
ContainerMetaDataImpl(BasicEObjectImpl).eInternalResource() line: 925
ContainerMetaDataImpl(CDOObjectImpl).eInternalResource() line: 622
ContainerMetaDataImpl(BasicEObjectImpl).eResource() line: 920
ContainerMetaDataImpl(CDOObjectImpl).cdoResource() line: 195
CDOModificationTrackingAdapter(CDOLazyContentAdapter).isContained(CDOObject) line: 209
CDOLazyContentAdapter.access$2(CDOLazyContentAdapter, CDOObject) line: 194
CDOLazyContentAdapter$CleanObjectHandler.objectStateChanged(CDOView, CDOObject, CDOState, CDOState) line: 224
CDOTransactionImpl(AbstractCDOView).handleObjectStateChanged(InternalCDOObject, CDOState, CDOState) line: 2372
ContainerMetaDataImpl(CDOObjectImpl).cdoInternalSetState(CDOState) line: 302
CDOStateMachine.setState(InternalCDOObject, CDOState) line: 592
CDOStateMachine.setState(Object, Enum) line: 1
CDOStateMachine(FiniteStateMachine<STATE,EVENT,SUBJECT>).changeState(SUBJECT, STATE) line: 216
CDOStateMachine.access$2(CDOStateMachine, Object, Enum) line: 1
CDOStateMachine$CommitTransition.execute(InternalCDOObject, CDOState, CDOEvent, CDOSessionProtocol$CommitTransactionResult) line: 1060
CDOStateMachine$CommitTransition.execute(Object, Enum, Enum, Object) line: 1
CDOStateMachine(FiniteStateMachine<STATE,EVENT,SUBJECT>).process(SUBJECT, EVENT, DATA) line: 173
CDOStateMachine.commit(InternalCDOObject, CDOSessionProtocol$CommitTransactionResult) line: 542
CDOTransactionImpl$CDOCommitContextImpl.postCommit(Map<CDOID,CDOObject>, CommitTransactionResult) line: 4066
CDOTransactionImpl$CDOCommitContextImpl.postCommit(CDOSessionProtocol$CommitTransactionResult) line: 3913
As can be seen in the stack this results in the creation of a new resource instance although the resource has already been created. This results in a URI clash which is reported in the newResourceInstance method. As a result the model looses all objects contained in the original resource.
The reason for this is that the revision of ContainerMetaData already has a mapped ID (not temp any more). And the call to revision.getResourceID() also returns the server id of the resource. Since the id of the CDOResource itself which contains the ContainerMetaData has not yet been remapped (note that it would be processed right after the ContainerMetaData at position 100526), a lookup into the objects map of the transaction with the new server resource id reveals nothing.
I think that the CDOResource should be processed and remapped before it's containing ContainerMetaData object. This would happen if the entries would be processed in the same order as they were created. But as stated before, the ordering has for some reason changed.
Can someone please shed some light on this re-ording issue?
Thanks in advance
[Updated on: Mon, 11 April 2016 21:40]
Report message to a moderator
|Re: [CDO] Strange Commit Problem with URI Clash [message #1729225 is a reply to message #1729204]
||Tue, 12 April 2016 09:44
|| Eike Stepper
Registered: July 2009
I see what you mean. Please submit a bugzilla and I'll look at it...
Am 12.04.2016 um 09:07 schrieb Thorsten Schlathölter:
> I have checked the implementation for the new objects that are passed into postCommit. There is nohting more than a
> HashMap involved here. So the algorithm cannot rely on ordering. The problem I am facing here is the following.
> In the execute method of CDOStateMachine the ContainerMetaData object is processed. Note again that it is processed
> before it's CDOResource container is processed.
> public void execute(InternalCDOObject object, CDOState state, CDOEvent event, CommitTransactionResult data)
> InternalCDOTransaction transaction = object.cdoView().toTransaction();
> InternalCDORevision revision = object.cdoRevision();
> Map<CDOID, CDOID> idMappings = data.getIDMappings();
> // Adjust object
> CDOID oldID = object.cdoID();
> CDOID newID = idMappings.get(oldID);
> if (newID != null)
> // Adjust revision
> revision.adjustForCommit(transaction.getBranch(), data.getTimeStamp());
> InternalCDORevisionManager revisionManager = transaction.getSession().getRevisionManager();
> changeState(object, CDOState.CLEAN);
> After the object is remapped in the transaction, Its revision gets it references adjusted. The reference adjuster sets
> to resourceId of the ContainerMetaData revision to the new resourceId which is provided by the idMappings. Therefore
> when the direct resource of ContainerMetaData is getting resolved, the new id is used to lookup the CDOResource in the
> the Transaction. Unfortunately at this point in time the Transaction only knows the CDOResource by its old temporary
> ID as it has not yet been remapped. So no CDOResource is found and a new one is being requested causing the URI clash.
> It looks like the algorithm can work properly only if the CDOResource is remapped before it's contained children.
> Any thoughts?
Current Time: Thu Mar 22 00:42:21 GMT 2018
Powered by FUDForum
. Page generated in 0.01818 seconds