Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
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 Go to next message
Alex Lagarde is currently offline Alex LagardeFriend
Messages: 193
Registered: May 2010
Senior Member

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 Go to previous messageGo to next message
Alex Lagarde is currently offline Alex LagardeFriend
Messages: 193
Registered: May 2010
Senior Member

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 Go to previous messageGo to next message
Alex Lagarde is currently offline Alex LagardeFriend
Messages: 193
Registered: May 2010
Senior Member

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 Go to previous messageGo to next message
Eike Stepper is currently offline Eike StepperFriend
Messages: 6683
Registered: July 2009
Senior Member
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


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 Go to previous message
Alex Lagarde is currently offline Alex LagardeFriend
Messages: 193
Registered: May 2010
Senior Member

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".
Previous Topic:HibernateStore Vs Teneo Queries Functionalities
Next Topic:Creating new model code
Goto Forum:
  


Current Time: Sun May 05 19:34:51 GMT 2024

Powered by FUDForum. Page generated in 0.03888 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top