Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » EMF » [CDO] NPE when resolving proxy in delegating list
[CDO] NPE when resolving proxy in delegating list [message #1006207] Wed, 30 January 2013 08:07 Go to next message
Christophe Bouhier is currently offline Christophe Bouhier
Messages: 914
Registered: July 2009
Senior Member
Hello,

I have this interesting case which is:

Create CDO Object type 'B'.
Create a CDO Object type 'A', which has mulivalued EReference to CDO Object type 'B'

Store both in a regular EMF resource. (Not a CDO Resource).

then put object 'A' in a CDO Resource and commit.
When accessing the reference I get the exception below, which kind of makes sense, as B was not committed, but likely marked proxy as 'B' still exists in an regular EMF resource.

The interresting thing is, that when the EReference is single-valued, then I can check the
object with:

private boolean isExternal(EObject eo, EReference eRef) {
		if (eo instanceof CDOObject) {
			CDOObject cdoObject = CDOUtil.getCDOObject(eo);
			if (cdoObject != null && cdoObject.cdoID() != null) {
				return cdoObject.cdoID().isExternal();
			} else {
				return true;
			}

		}
		return false;
	}


However for a multivalued EReference, I don't know how to check this. Is there a way to
clean this object of invalid/external references when the EReference is multiplicity?

The Exception, the owner object = null

java.lang.NullPointerException
at org.eclipse.emf.ecore.util.DelegatingEcoreEList.resolveProxy(DelegatingEcoreEList.java:318)
at org.eclipse.emf.ecore.util.DelegatingEcoreEList.resolve(DelegatingEcoreEList.java:279)
at org.eclipse.emf.common.util.DelegatingEList.get(DelegatingEList.java:236)
at org.eclipse.emf.ecore.util.DelegatingEcoreEList.toArray(DelegatingEcoreEList.java:328)
at java.util.Collections$UnmodifiableCollection.toArray(Collections.java:1058)
at java.util.ArrayList.<init>(ArrayList.java:151)


In the DB, the _list table, points to a negative cdo_value object.


cdo_source	cdo_idx	cdo_value
150	0	-467



You might wonder what the use case for this is. This is has to do with importing objects
from excel, and letting the user select which objects. Of course when references break, these should
be cleaned. Unfortunately the code out there, has not cleaned non-committed external references, hence the need to deal with this 'corrupt' data in the current code.

Thank you,
Christophe

Re: [CDO] NPE when resolving proxy in delegating list [message #1006225 is a reply to message #1006207] Wed, 30 January 2013 08:54 Go to previous messageGo to next message
Eike Stepper is currently offline Eike Stepper
Messages: 5499
Registered: July 2009
Senior Member
Am 30.01.2013 14:07, schrieb Christophe Bouhier:
> Hello,
> I have this interesting case which is:
> Create CDO Object type 'B'. Create a CDO Object type 'A', which has mulivalued EReference to CDO Object type 'B'
>
> Store both in a regular EMF resource. (Not a CDO Resource).
Because of "both" I assume that the "mulivalued EReference" is a cross reference that doesn't automatically pull in B.

> then put object 'A' in a CDO Resource and commit. When accessing the reference I get the exception below, which kind
> of makes sense, as B was not committed, but likely marked proxy as 'B' still exists in an regular EMF resource.
Why is B a proxy?

I don't think that an exception should occur here. And an NPE is not good anyway. We should ask Ed because it comes from
EMF!

> The interresting thing is, that when the EReference is single-valued, then I can check the object with:
> private boolean isExternal(EObject eo, EReference eRef) {
> if (eo instanceof CDOObject) {
> CDOObject cdoObject = CDOUtil.getCDOObject(eo);
Just cast down here.

> if (cdoObject != null && cdoObject.cdoID() != null) {
The you don't need the not null check, either.

> return cdoObject.cdoID().isExternal();
> } else {
> return true;
> }
>
> }
> return false;
> }
>
>
> However for a multivalued EReference, I don't know how to check this. Is there a way to clean this object of
> invalid/external references when the EReference is multiplicity?
> The Exception, the owner object = null
>
> java.lang.NullPointerException
> at org.eclipse.emf.ecore.util.DelegatingEcoreEList.resolveProxy(DelegatingEcoreEList.java:318)
For me this line is in toArray(). What EMF and CDO versions do you use?

Fortunately resolveProxy() has just 1 line. Can you set a breakpoint in
DelegatingEcoreEList.DelegatingEcoreEList(InternalEObject) and try to find out why the owner is null?

> at org.eclipse.emf.ecore.util.DelegatingEcoreEList.resolve(DelegatingEcoreEList.java:279)
> at org.eclipse.emf.common.util.DelegatingEList.get(DelegatingEList.java:236)
> at org.eclipse.emf.ecore.util.DelegatingEcoreEList.toArray(DelegatingEcoreEList.java:328)
> at java.util.Collections$UnmodifiableCollection.toArray(Collections.java:1058)
> at java.util.ArrayList.<init>(ArrayList.java:151)
>
>
> In the DB, the _list table, points to a negative cdo_value object.
>
> cdo_source cdo_idx cdo_value
> 150 0 -467
IIRC. negative IDs are an indirection into the cdo_ext_refs table, which would be correct in your case.

> You might wonder what the use case for this is.
No :P

External references are supported by CDO.

> This is has to do with importing objects
> from excel, and letting the user select which objects. Of course when references break, these should be cleaned.
> Unfortunately the code out there, has not cleaned non-committed external references, hence the need to deal with this
> 'corrupt' data in the current code.
The only requirement to commit an object with an external reference is that the referenced object has proper URI, i.e.
that it is contained by a resource. Target objects can be checked for being external by looking at their eResource().

Cheers
/Eike

----
http://www.esc-net.de
http://thegordian.blogspot.com
http://twitter.com/eikestepper
Re: [CDO] NPE when resolving proxy in delegating list [message #1006230 is a reply to message #1006225] Wed, 30 January 2013 09:20 Go to previous messageGo to next message
Christophe Bouhier is currently offline Christophe Bouhier
Messages: 914
Registered: July 2009
Senior Member
Eike,

point_by_point below. rgds C.

p.s. I found a solution, but it's a hack.

1) Iterate through the collection of referenced (Potentially external) objects.
2) Catch the NPE, on a collection.get(i).
3) Remove the reference with:
CDOUtil.cleanStaleReference(objectToCheck, eRef, i);



Am 30.01.2013 14:07, schrieb Christophe Bouhier:
> Hello,
> I have this interesting case which is:
> Create CDO Object type 'B'. Create a CDO Object type 'A', which has mulivalued EReference to CDO Object type 'B'
>
> Store both in a regular EMF resource. (Not a CDO Resource).
Because of "both" I assume that the "mulivalued EReference" is a cross reference that doesn't automatically pull in B.

[CB] Yes, although I am not sure how such an automatic pull-in should work.

> then put object 'A' in a CDO Resource and commit. When accessing the reference I get the exception below, which kind
> of makes sense, as B was not committed, but likely marked proxy as 'B' still exists in an regular EMF resource.
Why is B a proxy?
[CB] because resolveProxy is called ?

I don't think that an exception should occur here. And an NPE is not good anyway. We should ask Ed because it comes from
EMF!

[CB] Yes, I noticed..

> The interresting thing is, that when the EReference is single-valued, then I can check the object with:
> private boolean isExternal(EObject eo, EReference eRef) {
> if (eo instanceof CDOObject) {
> CDOObject cdoObject = CDOUtil.getCDOObject(eo);
Just cast down here.
[CB] ok, thanks.

> if (cdoObject != null && cdoObject.cdoID() != null) {
The you don't need the not null check, either.

> return cdoObject.cdoID().isExternal();
> } else {
> return true;
> }
>
> }
> return false;
> }
>
>
> However for a multivalued EReference, I don't know how to check this. Is there a way to clean this object of
> invalid/external references when the EReference is multiplicity?
> The Exception, the owner object = null
>
> java.lang.NullPointerException
> at org.eclipse.emf.ecore.util.DelegatingEcoreEList.resolveProxy(DelegatingEcoreEList.java:318)
For me this line is in toArray(). What EMF and CDO versions do you use?

Fortunately resolveProxy() has just 1 line. Can you set a breakpoint in
DelegatingEcoreEList.DelegatingEcoreEList(InternalEObject) and try to find out why the owner is null?

[CB] sorry not owner, but the eObject itself is null. null is returned from this method:
protected E delegateGet(int index)
{
return delegateList().get(index);
}

The reason is likely that the external reference is not a valid filename but a temp file name I used
to store the objects in an EMF Resource. Anyway, it's about correcting the problem now.

> at org.eclipse.emf.ecore.util.DelegatingEcoreEList.resolve(DelegatingEcoreEList.java:279)
> at org.eclipse.emf.common.util.DelegatingEList.get(DelegatingEList.java:236)
> at org.eclipse.emf.ecore.util.DelegatingEcoreEList.toArray(DelegatingEcoreEList.java:328)
> at java.util.Collections$UnmodifiableCollection.toArray(Collections.java:1058)
> at java.util.ArrayList.<init>(ArrayList.java:151)
>
>
> In the DB, the _list table, points to a negative cdo_value object.
>
> cdo_source cdo_idx cdo_value
> 150 0 -467
IIRC. negative IDs are an indirection into the cdo_ext_refs table, which would be correct in your case.

> You might wonder what the use case for this is.
No Razz

External references are supported by CDO.


> This is has to do with importing objects
> from excel, and letting the user select which objects. Of course when references break, these should be cleaned.
> Unfortunately the code out there, has not cleaned non-committed external references, hence the need to deal with this
> 'corrupt' data in the current code.
The only requirement to commit an object with an external reference is that the referenced object has proper URI, i.e.
that it is contained by a resource. Target objects can be checked for being external by looking at their eResource().

[CB] considering, that I can't get the object, there is no way I can look at the eResource().

Cheers
/Eike
Re: [CDO] NPE when resolving proxy in delegating list [message #1006362 is a reply to message #1006230] Wed, 30 January 2013 23:46 Go to previous messageGo to next message
Eike Stepper is currently offline Eike Stepper
Messages: 5499
Registered: July 2009
Senior Member
Hi Christoph,

Just a thought, is your external resource cointained by the same resource set as the CDO resource(s)? Does it have a
proper URI?

Cheers
/Eike

----
http://www.esc-net.de
http://thegordian.blogspot.com
http://twitter.com/eikestepper


Am 30.01.2013 15:20, schrieb Christophe Bouhier:
> Eike,
> point_by_point below. rgds C.
> p.s. I found a solution, but it's a hack.
> 1) Iterate through the collection of referenced (Potentially external) objects. 2) Catch the NPE, on a
> collection.get(i). 3) Remove the reference with: CDOUtil.cleanStaleReference(objectToCheck, eRef, i);
>
>
>
> Am 30.01.2013 14:07, schrieb Christophe Bouhier:
>> Hello,
>> I have this interesting case which is:
>> Create CDO Object type 'B'. Create a CDO Object type 'A', which has mulivalued EReference to CDO Object type 'B'
>>
>> Store both in a regular EMF resource. (Not a CDO Resource).
> Because of "both" I assume that the "mulivalued EReference" is a cross reference that doesn't automatically pull in B.
>
> [CB] Yes, although I am not sure how such an automatic pull-in should work.
>> then put object 'A' in a CDO Resource and commit. When accessing the reference I get the exception below, which kind
>> of makes sense, as B was not committed, but likely marked proxy as 'B' still exists in an regular EMF resource.
> Why is B a proxy?
> [CB] because resolveProxy is called ?
> I don't think that an exception should occur here. And an NPE is not good anyway. We should ask Ed because it comes
> from EMF!
>
> [CB] Yes, I noticed..
>
>> The interresting thing is, that when the EReference is single-valued, then I can check the object with:
>> private boolean isExternal(EObject eo, EReference eRef) {
>> if (eo instanceof CDOObject) {
>> CDOObject cdoObject = CDOUtil.getCDOObject(eo);
> Just cast down here.
> [CB] ok, thanks.
>> if (cdoObject != null && cdoObject.cdoID() != null) {
> The you don't need the not null check, either.
>
>> return cdoObject.cdoID().isExternal();
>> } else {
>> return true;
>> }
>>
>> }
>> return false;
>> }
>>
>>
>> However for a multivalued EReference, I don't know how to check this. Is there a way to clean this object of
>> invalid/external references when the EReference is multiplicity?
>> The Exception, the owner object = null
>>
>> java.lang.NullPointerException
>> at org.eclipse.emf.ecore.util.DelegatingEcoreEList.resolveProxy(DelegatingEcoreEList.java:318)
> For me this line is in toArray(). What EMF and CDO versions do you use?
>
> Fortunately resolveProxy() has just 1 line. Can you set a breakpoint in
> DelegatingEcoreEList.DelegatingEcoreEList(InternalEObject) and try to find out why the owner is null?
>
> [CB] sorry not owner, but the eObject itself is null. null is returned from this method: protected E delegateGet(int
> index) {
> return delegateList().get(index);
> }
>
> The reason is likely that the external reference is not a valid filename but a temp file name I used
> to store the objects in an EMF Resource. Anyway, it's about correcting the problem now.
>> at org.eclipse.emf.ecore.util.DelegatingEcoreEList.resolve(DelegatingEcoreEList.java:279)
>> at org.eclipse.emf.common.util.DelegatingEList.get(DelegatingEList.java:236)
>> at org.eclipse.emf.ecore.util.DelegatingEcoreEList.toArray(DelegatingEcoreEList.java:328)
>> at java.util.Collections$UnmodifiableCollection.toArray(Collections.java:1058)
>> at java.util.ArrayList.<init>(ArrayList.java:151)
>>
>>
>> In the DB, the _list table, points to a negative cdo_value object.
>>
>> cdo_source cdo_idx cdo_value
>> 150 0 -467
> IIRC. negative IDs are an indirection into the cdo_ext_refs table, which would be correct in your case.
>
>> You might wonder what the use case for this is.
> No :p
>
> External references are supported by CDO.
>
>
>> This is has to do with importing objects
>> from excel, and letting the user select which objects. Of course when references break, these should be cleaned.
>> Unfortunately the code out there, has not cleaned non-committed external references, hence the need to deal with this
>> 'corrupt' data in the current code.
> The only requirement to commit an object with an external reference is that the referenced object has proper URI, i.e.
> that it is contained by a resource. Target objects can be checked for being external by looking at their eResource().
>
> [CB] considering, that I can't get the object, there is no way I can look at the eResource().
> Cheers
> /Eike
Re: [CDO] NPE when resolving proxy in delegating list [message #1006392 is a reply to message #1006362] Thu, 31 January 2013 03:38 Go to previous messageGo to next message
Christophe Bouhier is currently offline Christophe Bouhier
Messages: 914
Registered: July 2009
Senior Member
Eike,

No, it's a different ResourceSet.

This is how I create the Resource.

Resource resource = new ResourceSetImpl().createResource(URI
.createURI("temp"));

It's a valid URI, but it won't resolve. I just need the Resource to hold objects
temporarily (Until some of them are transferred to the CDO Resource and committed).

I think, what I would need is some sort of volatile Resource, but when not available, somehow CDO/EMF should return the proxy object with limited info. i.e. the URI only. I think the similar pattern as the CDOStaleReferencePolicy does. Wouldn't a stale reference policy also apply to external references? I mean if the URI, can't be resolved wouldn't this deserve similar treatment?

Perhaps there is another way around the problem of holding objects temporarily before committing, I need the EMF behavior (Before I pass them on to CDO), which is really 'moving' an object from one container to another. I don't know how to do this, if the container is not an EMF resource.

Thx Christophe


Re: [CDO] NPE when resolving proxy in delegating list [message #1006395 is a reply to message #1006392] Thu, 31 January 2013 03:51 Go to previous messageGo to next message
Eike Stepper is currently offline Eike Stepper
Messages: 5499
Registered: July 2009
Senior Member
Am 31.01.2013 09:38, schrieb Christophe Bouhier:
> Eike,
> No, it's a different ResourceSet.
Hehe, that can't work!

> This is how I create the Resource.
> Resource resource = new ResourceSetImpl().createResource(URI
> .createURI("temp"));
>
> It's a valid URI, but it won't resolve.
Guess what's supposed to resolve this URI :P

> I just need the Resource to hold objects temporarily (Until some of them are transferred to the CDO Resource and
> committed).
Just add that resource to The resource set that's managed by CDO.

Cheers
/Eike

----
http://www.esc-net.de
http://thegordian.blogspot.com
http://twitter.com/eikestepper


>
> I think, what I would need is some sort of volatile Resource, but when not available, somehow CDO/EMF should return
> the proxy object with limited info. i.e. the URI only. I think the similar pattern as the CDOStaleReferencePolicy
> does. Wouldn't a stale reference policy also apply to external references? I mean if the URI, can't be resolved
> wouldn't this deserve similar treatment?
> Perhaps there is another way around the problem of holding objects temporarily before committing, I need the EMF
> behavior (Before I pass them on to CDO), which is really 'moving' an object from one container to another. I don't
> know how to do this, if the container is not an EMF resource.
> Thx Christophe
>
>
>
Re: [CDO] NPE when resolving proxy in delegating list [message #1006397 is a reply to message #1006395] Thu, 31 January 2013 04:05 Go to previous messageGo to next message
Christophe Bouhier is currently offline Christophe Bouhier
Messages: 914
Registered: July 2009
Senior Member
Can you elaborate why this is? Something to do with URI Converters? I would like to understand this a bit better.
Thank you!
Re: [CDO] NPE when resolving proxy in delegating list [message #1006400 is a reply to message #1006397] Thu, 31 January 2013 04:10 Go to previous message
Eike Stepper is currently offline Eike Stepper
Messages: 5499
Registered: July 2009
Senior Member
Am 31.01.2013 10:05, schrieb Christophe Bouhier:
> Can you elaborate why this is? Something to do with URI Converters? I would like to understand this a bit better.
> Thank you!
In EMF proy URIs are resolved by the resource set that contains the referencing object. The referenced object must be
contained by the same resource set.

Cheers
/Eike

----
http://www.esc-net.de
http://thegordian.blogspot.com
http://twitter.com/eikestepper
Previous Topic:Where can I find Ecore.ecore
Next Topic:CDO lock/unlock
Goto Forum:
  


Current Time: Fri Aug 22 02:05:02 EDT 2014

Powered by FUDForum. Page generated in 0.02502 seconds