Home » Modeling » EMF » UnresolvedReferenceException an ID
| | |
Re: UnresolvedReferenceException an ID [message #657450 is a reply to message #657436] |
Wed, 02 March 2011 19:47 |
Ed Merks Messages: 33139 Registered: July 2009 |
Senior Member |
|
|
Comments below.
Xavipen wrote:
> Hi Ed,
>
> Thanks for your quick response.
>
> Quote:
>> Xavipen,
>>
>> Comments below.
>>
>> >Xavipen wrote:
>> > Hi,
>> >
>> > I was performing some test with the XMLResource when i run into
>> some > troubles.
>> >
>> > I have created a model with a non-containment reference. Which i
>> know > is going to fail when i call save.
>> > I also pass the option
>> XMIResource.OPTION_PROCESS_DANGLING_HREF_RECORD > to prevent the save
>> from throwing an exception.
>> > When i load the model there are no errors an everything is fine.
>> >
>> > However this behaviour changes a lot when the object to which the >
>> non-containment reference refers has one attribute set to ID.
>> >
>> > On the Save:
>> > - No errors are shown or exception is thrown.
>> It just uses the ID in that case I guess?
>
>
> Yes, it uses the id.
> The issue that i see is that you do not get any indication that
> something was missing and you may thing everything is fine with the
> model when you save it.
> I would have though that this would be checked like is done when the
> ID is not use and null would have been set in that case, so the load
> would not fail.
> Two more things consecuence of the above:
> 1) Is there any option to prevent the load from throwing an Exception?
> . The XMIResource.OPTION_PROCESS_DANGLING_HREF_RECORD doesn't do the
> trick :cry:
No, but keep in mind that the resource is fully loaded and available for
use...
> 2) Checking the dignostic messages return when loading i see that
> another valid object which is persisted has a diagnostic of
> IllegalValueException. Maybe here i should add that the
> "unresolvedreference" is within a list.
>
> Quote:
>> >
>> > On the Load:
>> > - the UnresolvedReferenceException is thrown regardless of the
>> option > XMIResource.OPTION_PROCESS_DANGLING_HREF_RECORD >
>> XMIResource.OPTION_PROCESS_DANGLING_HREF_RECORD
>> >
>> > Could anyone give me some hints on how is the best way to deal with
>> > this scenario in order to have similar behaviour when ID is set to
>> > true than when is set to false.
>> It's better to use things like EcoreUtil.delete to remove objects and
>> all references to them.
>
>
> Thanks for the the hint EcoreUtil.delete will be quite handy. :) And
> i would definetely use it.
>
> Unfortunatelly my concern when setting up this set of tests was to see
> how the persistance would behave in case there where
> hanging/unresolved references. So the model could be loaded again and
> regardless error the save a load would set the hanging references to
> null. This works pretty well when the ID is not use but not quite when
> is use.
>
> I could send the test case if you want
I'm not keen on adding checks during serialization. It's quite
expensive to determine if an object is contained by a resource. For an
HREF, we have to do that check anyway to build a cross resource URI, but
for an IDREF, we don't.
If you want to be sure you save only good instances, you should use
Diagnostician.INSTANCE.validate to find all the problems. E.g., to
find cases where more than one object has the same ID.
>
>>
>> Thanks in advance!
>> [/quote]
>
> Cheers,
>
Ed Merks
Professional Support: https://www.macromodeling.com/
|
|
|
Re: UnresolvedReferenceException an ID [message #657466 is a reply to message #657450] |
Wed, 02 March 2011 20:45 |
Xavipen Mising name Messages: 59 Registered: March 2011 |
Member |
|
|
Ed,
Comments below.
Xavipen wrote:
> > Hi Ed,
> >
> > Thanks for your quick response.
> >
> > Quote:
>> >> Xavipen,
>> >>
>> >> Comments below.
>> >>
>>> >> >Xavipen wrote:
>>> >> > Hi,
>>> >> >
>>> >> > I was performing some test with the XMLResource when i run into
>> >> some > troubles.
>>> >> >
>>> >> > I have created a model with a non-containment reference. Which i
>> >> know > is going to fail when i call save.
>>> >> > I also pass the option
>> >> XMIResource.OPTION_PROCESS_DANGLING_HREF_RECORD > to prevent the save
>> >> from throwing an exception.
>>> >> > When i load the model there are no errors an everything is fine.
>>> >> >
>>> >> > However this behaviour changes a lot when the object to which the >
>> >> non-containment reference refers has one attribute set to ID.
>>> >> >
>>> >> > On the Save:
>>> >> > - No errors are shown or exception is thrown.
>> >> It just uses the ID in that case I guess?
> >
> >
> > Yes, it uses the id.
> > The issue that i see is that you do not get any indication that
> > something was missing and you may thing everything is fine with the
> > model when you save it.
> > I would have though that this would be checked like is done when the
> > ID is not use and null would have been set in that case, so the load
> > would not fail.
> > Two more things consecuence of the above:
> > 1) Is there any option to prevent the load from throwing an Exception?
> > . The XMIResource.OPTION_PROCESS_DANGLING_HREF_RECORD doesn't do the
> > trick
> No, but keep in mind that the resource is fully loaded and available for
> use...
> > 2) Checking the dignostic messages return when loading i see that
> > another valid object which is persisted has a diagnostic of
> > IllegalValueException. Maybe here i should add that the
> > "unresolvedreference" is within a list.
> >
> > Quote:
>>> >> >
>>> >> > On the Load:
>>> >> > - the UnresolvedReferenceException is thrown regardless of the
>> >> option > XMIResource.OPTION_PROCESS_DANGLING_HREF_RECORD >
>> >> XMIResource.OPTION_PROCESS_DANGLING_HREF_RECORD
>>> >> >
>>> >> > Could anyone give me some hints on how is the best way to deal with
>>> >> > this scenario in order to have similar behaviour when ID is set to
>>> >> > true than when is set to false.
>> >> It's better to use things like EcoreUtil.delete to remove objects and
>> >> all references to them.
> >
> >
> > Thanks for the the hint EcoreUtil.delete will be quite handy. And
> > i would definetely use it.
> >
> > Unfortunatelly my concern when setting up this set of tests was to see
> > how the persistance would behave in case there where
> > hanging/unresolved references. So the model could be loaded again and
> > regardless error the save a load would set the hanging references to
> > null. This works pretty well when the ID is not use but not quite when
> > is use.
> >
> > I could send the test case if you want
>I'm not keen on adding checks during serialization. It's quite
expensive to determine if an object is contained by a resource. For an
HREF, we have to do that check anyway to build a cross resource URI, but
for an IDREF, we don't.
>If you want to be sure you save only good instances, you should use
Diagnostician.INSTANCE.validate to find all the problems. E.g., to
find cases where more than one object has the same ID.
> >
>> >>
>> >> Thanks in advance!
>> >> [/quote]
> >
> > Cheers,
I understand your point about not adding the check and i could live with no getting any error, although is not ideal. (Diagnostician.INSTANCE.validate does not raise any error neither)
However, it seems to be a problem with the load of the resource loaded from the test model.
I maybe able to explain it better with an example.
The Model is as follow
The root object has two list contaiment lit of Class A and B. B has itself a non contaiment list of Objects A.
model is:
root
-> list ( A1, A4 )
-> list (B1, B2)
where:
B1 --> (A1,A2)
B2 --> (A1,A2,A3,A4)
I save it and then load it. The model loaded is fine except for B2.
instead of having B2--> (A1,A4)
it has B2 --> (A1)
So the reference to one valid object is also lost becasue of the unresolved references. This seems a bit Odd.
Cheers,
|
|
|
Re: UnresolvedReferenceException an ID [message #657483 is a reply to message #657466] |
Wed, 02 March 2011 23:01 |
Ed Merks Messages: 33139 Registered: July 2009 |
Senior Member |
|
|
This is a multi-part message in MIME format.
--------------090104060404090201080008
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 7bit
Comments below.
Xavipen wrote:
> Ed,
>
> Comments below.
>
> Xavipen wrote:
>> > Hi Ed,
>> >
>> > Thanks for your quick response.
>> >
>> > Quote:
>>> >> Xavipen,
>>> >>
>>> >> Comments below.
>>> >>
>>>> >> >Xavipen wrote:
>>>> >> > Hi,
>>>> >> >
>>>> >> > I was performing some test with the XMLResource when i run into
>>> >> some > troubles.
>>>> >> >
>>>> >> > I have created a model with a non-containment reference. Which i
>>> >> know > is going to fail when i call save.
>>>> >> > I also pass the option
>>> >> XMIResource.OPTION_PROCESS_DANGLING_HREF_RECORD > to prevent the
>>> save >> from throwing an exception.
>>>> >> > When i load the model there are no errors an everything is fine.
>>>> >> >
>>>> >> > However this behaviour changes a lot when the object to which
>>>> the >
>>> >> non-containment reference refers has one attribute set to ID.
>>>> >> >
>>>> >> > On the Save:
>>>> >> > - No errors are shown or exception is thrown.
>>> >> It just uses the ID in that case I guess?
>> >
>> >
>> > Yes, it uses the id.
>> > The issue that i see is that you do not get any indication that >
>> something was missing and you may thing everything is fine with the >
>> model when you save it.
>> > I would have though that this would be checked like is done when
>> the > ID is not use and null would have been set in that case, so the
>> load > would not fail.
>> > Two more things consecuence of the above:
>> > 1) Is there any option to prevent the load from throwing an
>> Exception? > . The XMIResource.OPTION_PROCESS_DANGLING_HREF_RECORD
>> doesn't do the > trick :cry:
>> No, but keep in mind that the resource is fully loaded and available
>> for use...
>> > 2) Checking the dignostic messages return when loading i see that >
>> another valid object which is persisted has a diagnostic of >
>> IllegalValueException. Maybe here i should add that the >
>> "unresolvedreference" is within a list.
>> >
>> > Quote:
>>>> >> >
>>>> >> > On the Load:
>>>> >> > - the UnresolvedReferenceException is thrown regardless of the
>>> >> option > XMIResource.OPTION_PROCESS_DANGLING_HREF_RECORD > >>
>>> XMIResource.OPTION_PROCESS_DANGLING_HREF_RECORD
>>>> >> >
>>>> >> > Could anyone give me some hints on how is the best way to deal
>>>> with >> > this scenario in order to have similar behaviour when ID
>>>> is set to >> > true than when is set to false.
>>> >> It's better to use things like EcoreUtil.delete to remove objects
>>> and >> all references to them.
>> >
>> >
>> > Thanks for the the hint EcoreUtil.delete will be quite handy. :)
>> And > i would definetely use it.
>> >
>> > Unfortunatelly my concern when setting up this set of tests was to
>> see > how the persistance would behave in case there where >
>> hanging/unresolved references. So the model could be loaded again and
>> > regardless error the save a load would set the hanging references
>> to > null. This works pretty well when the ID is not use but not
>> quite when > is use.
>> >
>> > I could send the test case if you want
>> I'm not keen on adding checks during serialization. It's quite
> expensive to determine if an object is contained by a resource. For
> an HREF, we have to do that check anyway to build a cross resource
> URI, but for an IDREF, we don't.
>
>> If you want to be sure you save only good instances, you should use
> Diagnostician.INSTANCE.validate to find all the problems. E.g., to
> find cases where more than one object has the same ID.
>> >
>>> >>
>>> >> Thanks in advance!
>>> >> [/quote]
>> >
>> > Cheers,
>
>
> I understand your point about not adding the check and i could live
> with no getting any error, although is not ideal.
> (Diagnostician.INSTANCE.validate does not raise any error neither)
Hmmm. EObjectValidator has this logic:
public boolean validate_EveryReferenceIsContained(EObject eObject,
DiagnosticChain diagnostics, Map<Object, Object> context)
{
boolean result = true;
if (eObject.eResource() != null)
{
for (EContentsEList.FeatureIterator<EObject> i =
(EContentsEList.FeatureIterator<EObject>)eObject.eCrossReferences().iterator();
i.hasNext(); )
{
EObject eCrossReferenceObject = i.next();
if (eCrossReferenceObject.eResource() == null &&
!eCrossReferenceObject.eIsProxy() && !i.feature().isTransient())
{
So for any object contained by a resource, if it has any cross
references not contained by a resource, there will be an error
produced. So I'm a little doubtful... that you'd not see a diagnostic.
Note that using Resource.getAllContents() and using
EObject.eCrossReferences() on each contained object, it's very easy to
check if eResource() is null for any of those (like what the above is
doing).
>
> However, it seems to be a problem with the load of the resource loaded
> from the test model.
>
> I maybe able to explain it better with an example.
>
> The Model is as follow
> The root object has two list contaiment lit of Class A and B. B has
> itself a non contaiment list of Objects A.
>
> model is:
> root
> -> list ( A1, A4 )
> -> list (B1, B2)
>
> where:
> B1 --> (A1,A2)
> B2 --> (A1,A2,A3,A4)
>
> I save it and then load it. The model loaded is fine except for B2.
>
> instead of having B2--> (A1,A4)
> it has B2 --> (A1)
>
> So the reference to one valid object is also lost becasue of the
> unresolved references. This seems a bit Odd.
If it's really important in your application to trap this, you could
specialize your ResourceImpl to check for "eObject.eResource() == this"
and return "/-1" if it's false.
public String getURIFragment(EObject eObject)
{
String id = EcoreUtil.getID(eObject);
if (id != null)
{
return id;
}
>
>
> Cheers,
--------------090104060404090201080008
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: 8bit
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html;charset=UTF-8" http-equiv="Content-Type">
</head>
<body bgcolor="#ffffff" text="#000000">
Comments below.<br>
<br>
Xavipen wrote:
<blockquote cite="mid:ikm9ta$mj6$1@news.eclipse.org" type="cite">Ed,
<br>
<br>
Comments below.
<br>
<br>
Xavipen wrote:
<br>
<blockquote type="cite">> Hi Ed,
<br>
>
<br>
> Thanks for your quick response.
<br>
>
<br>
> Quote:
<br>
<blockquote type="cite">>> Xavipen,
<br>
>>
<br>
>> Comments below.
<br>
>>
<br>
<blockquote type="cite">>> >Xavipen wrote:
<br>
>> > Hi,
<br>
>> >
<br>
>> > I was performing some test with the XMLResource when i
run into </blockquote>
>> some > troubles.
<br>
<blockquote type="cite">>> >
<br>
>> > I have created a model with a non-containment reference.
Which i </blockquote>
>> know > is going to fail when i call save.
<br>
<blockquote type="cite">>> > I also pass the option </blockquote>
>> XMIResource.OPTION_PROCESS_DANGLING_HREF_RECORD > to
prevent the save >> from throwing an exception.
<br>
<blockquote type="cite">>> > When i load the model there
are no errors an everything is fine.
<br>
>> >
<br>
>> > However this behaviour changes a lot when the object to
which the > </blockquote>
>> non-containment reference refers has one attribute set to ID.
<br>
<blockquote type="cite">>> >
<br>
>> > On the Save:
<br>
>> > - No errors are shown or exception is thrown.
<br>
</blockquote>
>> It just uses the ID in that case I guess?
<br>
</blockquote>
>
<br>
>
<br>
> Yes, it uses the id.
<br>
> The issue that i see is that you do not get any indication that
> something was missing and you may thing everything is fine with
the > model when you save it.
<br>
> I would have though that this would be checked like is done when
the > ID is not use and null would have been set in that case, so
the load > would not fail.
<br>
> Two more things consecuence of the above:
<br>
> 1) Is there any option to prevent the load from throwing an
Exception? > . The XMIResource.OPTION_PROCESS_DANGLING_HREF_RECORD
doesn't do the > trick :cry:
<br>
No, but keep in mind that the resource is fully loaded and available
for use...
<br>
> 2) Checking the dignostic messages return when loading i see that
> another valid object which is persisted has a diagnostic of >
IllegalValueException. Maybe here i should add that the >
"unresolvedreference" is within a list.
<br>
>
<br>
> Quote:
<br>
<blockquote type="cite">
<blockquote type="cite">>> >
<br>
>> > On the Load:
<br>
>> > - the UnresolvedReferenceException is thrown regardless
of the </blockquote>
>> option > XMIResource.OPTION_PROCESS_DANGLING_HREF_RECORD
> >> XMIResource.OPTION_PROCESS_DANGLING_HREF_RECORD
<br>
<blockquote type="cite">>> >
<br>
>> > Could anyone give me some hints on how is the best way to
deal with >> > this scenario in order to have similar
behaviour when ID is set to >> > true than when is set to
false.
<br>
</blockquote>
>> It's better to use things like EcoreUtil.delete to remove
objects and >> all references to them.
<br>
</blockquote>
>
<br>
>
<br>
> Thanks for the the hint EcoreUtil.delete will be quite handy. :)
And > i would definetely use it.
<br>
>
<br>
> Unfortunatelly my concern when setting up this set of tests was to
see > how the persistance would behave in case there where >
hanging/unresolved references. So the model could be loaded again and
> regardless error the save a load would set the hanging references
to > null. This works pretty well when the ID is not use but not
quite when > is use.
<br>
>
<br>
> I could send the test case if you want
<br>
I'm not keen on adding checks during serialization. It's quite </blockquote>
expensive to determine if an object is contained by a resource. For an
HREF, we have to do that check anyway to build a cross resource URI,
but for an IDREF, we don't.
<br>
<br>
<blockquote type="cite">If you want to be sure you save only good
instances, you should use </blockquote>
Diagnostician.INSTANCE.validate to find all the problems. E.g., to
find cases where more than one object has the same ID.
<br>
<blockquote type="cite">>
<br>
<blockquote type="cite">>>
<br>
>> Thanks in advance!
<br>
>> [/quote]
<br>
</blockquote>
>
<br>
> Cheers,
<br>
</blockquote>
<br>
<br>
I understand your point about not adding the check and i could live
with no getting any error, although is not ideal.
(Diagnostician.INSTANCE.validate does not raise any error neither)
<br>
</blockquote>
Hmmm. EObjectValidator has this logic:<br>
<blockquote><small> public boolean
validate_EveryReferenceIsContained(EObject eObject, DiagnosticChain
diagnostics, Map<Object, Object> context)</small><br>
<small> {</small><br>
<small> boolean result = true;</small><br>
<small> if (eObject.eResource() != null)</small><br>
<small> {</small><br>
<small> for (EContentsEList.FeatureIterator<EObject> i =
(EContentsEList.FeatureIterator<EObject>)eObje ct.eCrossReferences().iterator();
i.hasNext(); )</small><br>
<small> {</small><br>
<small> EObject eCrossReferenceObject = i.next();</small><br>
<small> if (eCrossReferenceObject.eResource() == null
&& !eCrossReferenceObject.eIsProxy() &&
!i.feature().isTransient())</small><br>
<small> {</small><br>
</blockquote>
So for any object contained by a resource, if it has any cross
references not contained by a resource, there will be an error
produced. So I'm a little doubtful... that you'd not see a
diagnostic. Note that using Resource.getAllContents() and using
EObject.eCrossReferences() on each contained object, it's very easy to
check if eResource() is null for any of those (like what the above is
doing).<br>
<blockquote cite="mid:ikm9ta$mj6$1@news.eclipse.org" type="cite"><br>
However, it seems to be a problem with the load of the resource loaded
from the test model.
<br>
<br>
I maybe able to explain it better with an example.
<br>
<br>
The Model is as follow
<br>
The root object has two list contaiment lit of Class A and B. B has
itself a non contaiment list of Objects A.
<br>
<br>
model is:
<br>
root
<br>
-> list ( A1, A4 )
<br>
-> list (B1, B2)
<br>
<br>
where:
<br>
B1 --> (A1,A2)
<br>
B2 --> (A1,A2,A3,A4)
<br>
<br>
I save it and then load it. The model loaded is fine except for B2.
<br>
<br>
instead of having B2--> (A1,A4)
<br>
it has B2 --> (A1)
<br>
<br>
So the reference to one valid object is also lost becasue of the
unresolved references. This seems a bit Odd.
<br>
</blockquote>
If it's really important in your application to trap this, you could
specialize your ResourceImpl to check for "eObject.eResource() == this"
and return "/-1" if it's false.<br>
<blockquote><small> public String getURIFragment(EObject eObject)</small><br>
<small> {</small><br>
<small> String id = EcoreUtil.getID(eObject);</small><br>
<small> if (id != null)</small><br>
<small> {</small><br>
<small> return id;</small><br>
<small> }</small><br>
</blockquote>
<blockquote cite="mid:ikm9ta$mj6$1@news.eclipse.org" type="cite"><br>
<br>
Cheers,
<br>
</blockquote>
</body>
</html>
--------------090104060404090201080008--
Ed Merks
Professional Support: https://www.macromodeling.com/
|
|
| | |
Re: UnresolvedReferenceException an ID [message #657655 is a reply to message #657638] |
Thu, 03 March 2011 15:31 |
Xavipen Mising name Messages: 59 Registered: March 2011 |
Member |
|
|
Ed,
The corrected code, I had mistaken one == for one !=. My apologies. I hope that know it would be easier to understand my question.
Quote: | Javi,
Commens below.
Xavipen wrote:
> Hi Ed,
>
> I have followed your indications and started having a look to
> specialize the ResourceImpl. I check code of the method you said and i
> believe i understand its logic but for one thing.
>
> Why check eObject.eResource() == this and not for eObject.eResource()
> == null?
Where are you referring to?
>
> likewise
> container.eDirectResource() == this and not
> container.eDirectResource() == null?
Where?
> At the end of the day if an object is contained by another resource it
> should be also ok. What i am missing?
I'm not sure.
|
I was talking about the ResourceImpl and the method getURIFragement
Quote: |
If it's really important in your application to trap this, you could
specialize your ResourceImpl to check for "eObject.eResource() == this"
and return "/-1" if it's false.
public String getURIFragment(EObject eObject)
{
String id = EcoreUtil.getID(eObject);
if (id != null)
{
return id;
}
|
so the specialize method would be:
public String getURIFragment(EObject eObject)
{
String id = EcoreUtil.getID(eObject);
if (id != null)
{
if ( eObject.eResource()== this){
return id;
}else{
return "/-1";
}
}
....
Why check eObject.eResource() == this and not for eObject.eResource() != null?
likewise if id == null the rest of the code on that method for ResourceImpl checks for container.eDirectResource() == this and not container.eDirectResource() != null?
....
if (internalEObject.eDirectResource() == this || unloadingContents != null && unloadingContents.contains(internalEObject))
{
return "/" + getURIFragmentRootSegment(eObject);
}
else
....
At the end of the day if an object is contained by another resource it should be also ok. What i am missing?
Cheers,
[Updated on: Fri, 04 March 2011 00:45] Report message to a moderator
|
|
|
Goto Forum:
Current Time: Tue Apr 23 06:57:00 GMT 2024
Powered by FUDForum. Page generated in 0.04608 seconds
|