Home » Modeling » EMF » [CDO] URI clash: resource being instantiated had same URI as a resource already present locally
[CDO] URI clash: resource being instantiated had same URI as a resource already present locally [message #748108] |
Mon, 24 October 2011 13:47 |
|
Hi everyone !
I'm facing an issue quite annoying with CDO :
if I create a resource with transaction.getOrCreateResource(path), and
add legacy objects in it, when I commit I get the following warning :
[CDO] URI clash: resource being instantiated had same URI as a resource
already present locally.
What happens : when my resource is created, it associated with a temp ID
("oid1").
Then when I push my transaction, in post-commit CDOLegacyAdapters try to
access to cdoResource(), which calls AbstractCDOView.getObject() with
the persisted OID of my Resource ("OID4").
When browsing through the "objects" map, the resource is not yet
registered with this ID, so we call createObject("OID4"), which calls
newResourceInstance().
In this method, we first try to determine if a resource with the same
URI exists in my ResourceSet. Of course it is the case, as
getOrCreateResource() adds the created resource to the resourceSet.
In fine, I've got two resources in my ResourceSet :
- one temporary resource that has been renamed by newResourceInstance()
"cdo:/repo1/myResource.renamed" (oid1)
- one persisted resource "cdo:/repo1/myResource" (OID4)
CDOTransactionImpl(AbstractCDOView).createObject(CDOID) line: 787
CDOTransactionImpl(AbstractCDOView).getObject(CDOID, boolean) line: 692
CDOTransactionImpl.getObject(CDOID, boolean) line: 1034
CDOTransactionImpl.getObject(CDOID, boolean) line: 1
CDOLegacyAdapter(CDOLegacyWrapper).getEObjectFromPotentialID(InternalCDOView, EStructuralFeature, Object) line: 703
CDOLegacyAdapter(CDOLegacyWrapper).revisionToInstanceResource() line: 437
CDOLegacyAdapter(CDOLegacyWrapper).cdoResource() line: 127
CDOLegacyAdapter(CDOLegacyWrapper).cdoResource() line: 1
CDOModificationTrackingAdapter(CDOLazyContentAdapter).isContained(CDOObject) line: 212
CDOLazyContentAdapter.access$2(CDOLazyContentAdapter, CDOObject) line: 197
CDOLazyContentAdapter$CleanObjectHandler.objectStateChanged(CDOView,
CDOObject, CDOState, CDOState) line: 227
CDOTransactionImpl(AbstractCDOView).handleObjectStateChanged(InternalCDOObject, CDOState, CDOState) line: 1132
CDOLegacyAdapter(CDOLegacyWrapper).cdoInternalSetState(CDOState) line: 151
CDOStateMachine.setState(InternalCDOObject, CDOState) line: 462
CDOStateMachine.setState(Object, Enum) line: 1
CDOStateMachine(FiniteStateMachine<STATE,EVENT,SUBJECT>).changeState(SUBJECT, STATE) line: 205
CDOStateMachine.access$2(CDOStateMachine, Object, Enum) line: 1
CDOStateMachine$CommitTransition.execute(InternalCDOObject, CDOState,
CDOEvent, CDOSessionProtocol$CommitTransactionResult) line: 759
CDOStateMachine$CommitTransition.execute(Object, Enum, Enum, Object)
line: 1
CDOStateMachine(FiniteStateMachine<STATE,EVENT,SUBJECT>).process(SUBJECT, EVENT, DATA) line: 162
CDOStateMachine.commit(InternalCDOObject,
CDOSessionProtocol$CommitTransactionResult) line: 432
CDOTransactionImpl$CDOCommitContextImpl.postCommit(Map<CDOID,CDOObject>, CommitTransactionResult) line: 2618
CDOTransactionImpl$CDOCommitContextImpl.postCommit(CDOSessionProtocol$CommitTransactionResult) line: 2484
CDOSingleTransactionStrategyImpl.commit(InternalCDOTransaction,
IProgressMonitor) line: 99
CDOTransactionImpl.commit(IProgressMonitor) line: 1069
CDOPushTransaction.push(IProgressMonitor) line: 245
CDOPushTransaction.push() line: 240
I don't see anything that I'm doing wrong, maybe the post-commit event
is sent to early, before the old temporary resource has been removed
from the ResourceSet's resources or the "objects" map has been updated ?
Thanks by advance for your help,
Alex
|
|
|
Re: [CDO] URI clash: resource being instantiated had same URI as a resource already present locally [message #748168 is a reply to message #748108] |
Mon, 24 October 2011 14:29 |
|
The problem seems to be caused by the fact that
registerObject(CDOResource@OID4) is called too late.
When it works (about 1 time out of 3), the
registerObject(CDOResource@OID4) is called in the following context :
Thread [main] (Suspended (breakpoint at line 1064 in AbstractCDOView))
CDOTransactionImpl(AbstractCDOView).registerObject(InternalCDOObject)
line: 1064
CDOLegacyAdapter(CDOLegacyWrapper).revisionToInstanceResource() line: 441
CDOLegacyAdapter(CDOLegacyWrapper).cdoResource() line: 127
CDOLegacyAdapter(CDOLegacyWrapper).cdoResource() line: 1
CDOModificationTrackingAdapter(CDOLazyContentAdapter).isContained(CDOObject) line: 212
CDOLazyContentAdapter.access$2(CDOLazyContentAdapter, CDOObject) line: 197
CDOLazyContentAdapter$CleanObjectHandler.objectStateChanged(CDOView,
CDOObject, CDOState, CDOState) line: 227
CDOTransactionImpl(AbstractCDOView).handleObjectStateChanged(InternalCDOObject, CDOState, CDOState) line: 1132
CDOLegacyAdapter(CDOLegacyWrapper).cdoInternalSetState(CDOState) line: 151
CDOStateMachine.setState(InternalCDOObject, CDOState) line: 462
CDOStateMachine.setState(Object, Enum) line: 1
CDOStateMachine(FiniteStateMachine<STATE,EVENT,SUBJECT>).changeState(SUBJECT, STATE) line: 205
CDOStateMachine.access$2(CDOStateMachine, Object, Enum) line: 1
CDOStateMachine$CommitTransition.execute(InternalCDOObject, CDOState,
CDOEvent, CDOSessionProtocol$CommitTransactionResult) line: 759
CDOStateMachine$CommitTransition.execute(Object, Enum, Enum, Object)
line: 1
CDOStateMachine(FiniteStateMachine<STATE,EVENT,SUBJECT>).process(SUBJECT, EVENT, DATA) line: 162
CDOStateMachine.commit(InternalCDOObject,
CDOSessionProtocol$CommitTransactionResult) line: 432
CDOTransactionImpl$CDOCommitContextImpl.postCommit(Map<CDOID,CDOObject>, CommitTransactionResult) line: 2618
CDOTransactionImpl$CDOCommitContextImpl.postCommit(CDOSessionProtocol$CommitTransactionResult) line: 2484
CDOSingleTransactionStrategyImpl.commit(InternalCDOTransaction,
IProgressMonitor) line: 99
CDOTransactionImpl.commit(IProgressMonitor) line: 1069
CDOPushTransaction.push(IProgressMonitor) line: 245
CDOPushTransaction.push() line: 240
In that case, when we try to get the cdoResource() of CDOLegacyAdapters,
the call to CDOTransactionImpl(AbstractCDOView).getObject(CDOID,
boolean) line: 692 does not lead to creation of a new CDOResource as the
"objects" map is up-to-date and contains "OID4".
Maybe I can do something to order the postCommitEvents ?
|
|
|
Re: [CDO] URI clash: resource being instantiated had same URI as a resource already present locally [message #748189 is a reply to message #748168] |
Mon, 24 October 2011 14:46 |
|
The following naive fix seems to work perfectly :
in the CDOTransactionImpl.postCommit() method, instead of sending the
StateMachine events to all newObjects without ordering the list, I first
send notifications to the CDOResource and then the CDOObjects :
private void postCommit(Map<CDOID, CDOObject> objects,
CommitTransactionResult result) {
if (!objects.isEmpty()) {
for (CDOObject object : objects.values()) {
if (object instanceof CDOResource) {
CDOStateMachine.INSTANCE.commit((InternalCDOObject) object, result);
}
}
for (CDOObject object : objects.values()) {
if (!(object instanceof CDOResource)) {
CDOStateMachine.INSTANCE.commit((InternalCDOObject) object, result);
}
}
}
}
Is this useless or too ugly ? I think that we should also order the
objects list by containment (send notifications to containers before
children), even if the newInstance(EClass eclass) does not lead to any
error. I may be missing the big picture, let me know if this fix makes
cense to you.
Alex
|
|
|
Re: [CDO] URI clash: resource being instantiated had same URI as a resource already present locally [message #749563 is a reply to message #748108] |
Tue, 25 October 2011 09:45 |
|
Hi Alex,
It sounds like an issue with the legacy mode. Have you tried the same client logic with native objects?
In any case please submit a bugzilla and we can dispatch it later to the appropriate team member.
Cheers
/Eike
----
http://www.esc-net.de
http://thegordian.blogspot.com
http://twitter.com/eikestepper
Am 24.10.2011 15:47, schrieb Alex Lagarde:
> Hi everyone !
>
> I'm facing an issue quite annoying with CDO :
>
> if I create a resource with transaction.getOrCreateResource(path), and add legacy objects in it, when I commit I get
> the following warning :
> [CDO] URI clash: resource being instantiated had same URI as a resource already present locally.
>
> What happens : when my resource is created, it associated with a temp ID ("oid1").
>
> Then when I push my transaction, in post-commit CDOLegacyAdapters try to access to cdoResource(), which calls
> AbstractCDOView.getObject() with the persisted OID of my Resource ("OID4").
>
> When browsing through the "objects" map, the resource is not yet registered with this ID, so we call
> createObject("OID4"), which calls newResourceInstance().
>
> In this method, we first try to determine if a resource with the same URI exists in my ResourceSet. Of course it is
> the case, as getOrCreateResource() adds the created resource to the resourceSet.
>
> In fine, I've got two resources in my ResourceSet :
> - one temporary resource that has been renamed by newResourceInstance() "cdo:/repo1/myResource.renamed" (oid1)
> - one persisted resource "cdo:/repo1/myResource" (OID4)
>
>
> CDOTransactionImpl(AbstractCDOView).createObject(CDOID) line: 787
> CDOTransactionImpl(AbstractCDOView).getObject(CDOID, boolean) line: 692
> CDOTransactionImpl.getObject(CDOID, boolean) line: 1034
> CDOTransactionImpl.getObject(CDOID, boolean) line: 1
> CDOLegacyAdapter(CDOLegacyWrapper).getEObjectFromPotentialID(InternalCDOView, EStructuralFeature, Object) line: 703
> CDOLegacyAdapter(CDOLegacyWrapper).revisionToInstanceResource() line: 437
> CDOLegacyAdapter(CDOLegacyWrapper).cdoResource() line: 127
> CDOLegacyAdapter(CDOLegacyWrapper).cdoResource() line: 1
> CDOModificationTrackingAdapter(CDOLazyContentAdapter).isContained(CDOObject) line: 212
> CDOLazyContentAdapter.access$2(CDOLazyContentAdapter, CDOObject) line: 197
> CDOLazyContentAdapter$CleanObjectHandler.objectStateChanged(CDOView, CDOObject, CDOState, CDOState) line: 227
> CDOTransactionImpl(AbstractCDOView).handleObjectStateChanged(InternalCDOObject, CDOState, CDOState) line: 1132
> CDOLegacyAdapter(CDOLegacyWrapper).cdoInternalSetState(CDOState) line: 151
> CDOStateMachine.setState(InternalCDOObject, CDOState) line: 462
> CDOStateMachine.setState(Object, Enum) line: 1
> CDOStateMachine(FiniteStateMachine<STATE,EVENT,SUBJECT>).changeState(SUBJECT, STATE) line: 205
> CDOStateMachine.access$2(CDOStateMachine, Object, Enum) line: 1
> CDOStateMachine$CommitTransition.execute(InternalCDOObject, CDOState, CDOEvent,
> CDOSessionProtocol$CommitTransactionResult) line: 759
> CDOStateMachine$CommitTransition.execute(Object, Enum, Enum, Object) line: 1
> CDOStateMachine(FiniteStateMachine<STATE,EVENT,SUBJECT>).process(SUBJECT, EVENT, DATA) line: 162
> CDOStateMachine.commit(InternalCDOObject, CDOSessionProtocol$CommitTransactionResult) line: 432
> CDOTransactionImpl$CDOCommitContextImpl.postCommit(Map<CDOID,CDOObject>, CommitTransactionResult) line: 2618
> CDOTransactionImpl$CDOCommitContextImpl.postCommit(CDOSessionProtocol$CommitTransactionResult) line: 2484
> CDOSingleTransactionStrategyImpl.commit(InternalCDOTransaction, IProgressMonitor) line: 99
> CDOTransactionImpl.commit(IProgressMonitor) line: 1069
> CDOPushTransaction.push(IProgressMonitor) line: 245
> CDOPushTransaction.push() line: 240
>
>
> I don't see anything that I'm doing wrong, maybe the post-commit event is sent to early, before the old temporary
> resource has been removed from the ResourceSet's resources or the "objects" map has been updated ?
>
> Thanks by advance for your help,
> Alex
Cheers
/Eike
----
http://www.esc-net.de
http://thegordian.blogspot.com
http://twitter.com/eikestepper
|
|
|
Re: [CDO] URI clash: resource being instantiated had same URI as a resource already present locally [message #749652 is a reply to message #749563] |
Tue, 25 October 2011 10:54 |
|
Hi Eike,
no, I did not try to reproduce the issue with native CDOObjects, as I
did not manage to identify a clear use case to reproduce the issue.
I've filed the following bugzilla ticket
https://bugs.eclipse.org/bugs/show_bug.cgi?id=361904 , under cdo.core as
I am not sure it is due to legacy mode, and also because the naive
solution I propose modifies AbstractCDOView in a non-impacting way
(according to me).
But by taking a closer look at CDOLegacyWrapper, I strongly suspect that
the issue is due to the call to revisionToInstanceResource() inside
cdoResource() : as we get the OID of the CDOResource of a
CDOLegacyWrapper that just has been updated, this returns OID4 although
the "objects" map of the transaction still maps this resource with "oid1".
|
|
|
Goto Forum:
Current Time: Sun May 05 19:34:51 GMT 2024
Powered by FUDForum. Page generated in 0.03888 seconds
|