Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » EMF "Technology" (Ecore Tools, EMFatic, etc)  » Sparse lists seem to cause havoc in Teneo 0.7.5
Sparse lists seem to cause havoc in Teneo 0.7.5 [message #125488] Sun, 08 June 2008 19:31 Go to next message
Eclipse UserFriend
Originally posted by: sprakash.tibco.com

Hello Martin,
We have Teneo-0.7.5 in production in some customer sites. There is this
problem that keeps cropping up, and while I cant share the exact details,
I thought I would bring the essential problem to your attention so that
you could consider fixing it in the 0.8 line, if you can figure out why
exactly it is happening. I cant provide an easy test case without getting
a ton of EMF models and DB data from the customer, and that wont be
possible.

Essential problem is that upon saving a Teneo resource, in these somewhat
random cases (i.e. I cant characterize the Hibernate query that forms
these resources very clearly), we get NPEs. The NPEs always occur in the
following three methods:
1)
org.eclipse.emf.teneo.resource.NonLoadingDiagnostician.doVal idateContents
- The NPE doesnt actually happen here, but this method has a line "result
&= validate(child, diagnostics, context);". The "validate" call to EMF
Ecore does not like Null "child" objects. Question is - why is Teneo
sending it nulls.
2) org.eclipse.emf.teneo.resource.attachedHelper
3) org.eclipse.emf.teneo.resource.detachedHelper
Both of the above methods also NPE on getting Null objects.

We have gotten around the problem by putting null checks in cases 2 and 3.
But I dont exactly understand why the nulls come in the first place
especially when the code is not expecting them. My guess is that Hibernate
is perhaps returning sparse lists in its queries (i.e. some elements are
null) and this creates trouble when you assemble EMF resources using these
objects(?). Is this a possibility? If so, should you be guarding against
such cases? Of course, if all of this is gone in 0.8, that's great (I
havent been able to test these cases with 0.8 because I need to migrate
the problematic data).

Thanks,

Sundeep
Re: Sparse lists seem to cause havoc in Teneo 0.7.5 [message #125502 is a reply to message #125488] Sun, 08 June 2008 19:49 Go to previous messageGo to next message
Martin Taal is currently offline Martin TaalFriend
Messages: 5468
Registered: July 2009
Senior Member
Hi Sundeep,
Can you send me the stack trace with the npe? I am mainly interested in the exact line in the
attachedHelper and detachedHelper methods you get this exception. If you can also post the source
code that would be nice to.

If you think the cause is sparse lists then the following can result in null-entries in a list:
- A list is persisted as a foreign key from the child to parent (so not using a join table)
- The list is mapped as a list (so with an index column).
- The child is removed from the db without loading the parent.

As an example: assume an object p has a list of objects o1 and o2, in the db o1 has a foreign key to
p with index column 0, and o2 has a foreign key to p with index column 1. Then in a new session o1
is read and removed (from the db). Then the db has the record for p and o2 with index 1. If p is
read then o2 is placed in position 1 in the list and position 0 will have a null entry in the list.

Can this occur in this case?

gr. Martin

Sundeep Prakash wrote:
> Hello Martin,
> We have Teneo-0.7.5 in production in some customer sites. There is this
> problem that keeps cropping up, and while I cant share the exact
> details, I thought I would bring the essential problem to your attention
> so that you could consider fixing it in the 0.8 line, if you can figure
> out why exactly it is happening. I cant provide an easy test case
> without getting a ton of EMF models and DB data from the customer, and
> that wont be possible.
>
> Essential problem is that upon saving a Teneo resource, in these
> somewhat random cases (i.e. I cant characterize the Hibernate query that
> forms these resources very clearly), we get NPEs. The NPEs always occur
> in the following three methods:
> 1)
> org.eclipse.emf.teneo.resource.NonLoadingDiagnostician.doVal idateContents
> - The NPE doesnt actually happen here, but this method has a line
> "result &= validate(child, diagnostics, context);". The "validate" call
> to EMF Ecore does not like Null "child" objects. Question is - why is
> Teneo sending it nulls.
> 2) org.eclipse.emf.teneo.resource.attachedHelper
> 3) org.eclipse.emf.teneo.resource.detachedHelper
> Both of the above methods also NPE on getting Null objects.
> We have gotten around the problem by putting null checks in cases 2 and
> 3. But I dont exactly understand why the nulls come in the first place
> especially when the code is not expecting them. My guess is that
> Hibernate is perhaps returning sparse lists in its queries (i.e. some
> elements are null) and this creates trouble when you assemble EMF
> resources using these objects(?). Is this a possibility? If so, should
> you be guarding against such cases? Of course, if all of this is gone in
> 0.8, that's great (I havent been able to test these cases with 0.8
> because I need to migrate the problematic data).
>
> Thanks,
>
> Sundeep
>


--

With Regards, Martin Taal

Springsite/Elver.org
Office: Hardwareweg 4, 3821 BV Amersfoort
Postal: Nassaulaan 7, 3941 EC Doorn
The Netherlands
Cell: +31 (0)6 288 48 943
Tel: +31 (0)84 420 2397
Fax: +31 (0)84 225 9307
Mail: mtaal@springsite.com - mtaal@elver.org
Web: www.springsite.com - www.elver.org
Re: Sparse lists seem to cause havoc in Teneo 0.7.5 [message #125934 is a reply to message #125502] Fri, 13 June 2008 21:23 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: sprakash.tibco.com

Hello Martin,
Thank you very much for devoting your time to address this issue. To
answer your question, yes we definitely satisfy conditions 1 and 2 i.e. I
believe the list is persisted as a foreign key from child to parent, and
the list is mapped as a list with an index column. But I am quite sure
condition 3 is not satisfied, i.e. do not remove the child without loading
the parent. I believe that if we did, we would get sparse lists even for
simple queries. We get sparse lists only when we have rather large queries
with lots of join conditions, not on simple queries.

Also, more detail as to the (now 4) places where I have seen NPEs (To
prevent them, I have guarded them myself, see the code between "Begin
Sundeep Addition" and "End Sundeep Addition" in each of the 4 methods
below to see where the NPE occurred).

Regards,

Sundeep

The four pieces of code from Teneo 0.7.5 follow:

1) org.eclipse.emf.teneo.resource.attachedHelper: (The NPE is immediately
thrown on hitting the eObject.eContainer() line because eObject is null)
---------------------------
protected void attachedHelper(EObject eObject) {

// Begin Sundeep Addition
if (eObject == null) return;
// End Sundeep Addition
// also attach the container
if (eObject.eContainer() != null && eObject.eContainer().eResource() ==
null &&
!eObject.eContainmentFeature().isResolveProxies()) {
attached(eObject.eContainer());
}

// a bit strange as an object can only be contained once but this can
happen if someone
// adds an object to a resource directly and then later add this same
object as a child
// to a container
if (newEObjects.contains(eObject) || loadedEObjects.contains(eObject))
return;

// Already belongs to another resource
if (eObject.eResource() != null && eObject.eResource() != this) {
return;
}

addedEObject(eObject);

if (eObject instanceof InternalEObject && eObject.eResource() == null) {
setEResource((InternalEObject)eObject, false);
}

// only add an eobject to contents if it does not have a container or if
the container
// relation allows resolve proxies (container and contained can be in
different resources)
// and the load strategy is correct
if ((eObject.eContainer() == null || eObject.eContainmentFeature() ==
null ||
eObject.eContainmentFeature().isResolveProxies()) &&
!getSuperContents().contains(eObject) &&
loadStrategy.compareTo(ADD_TO_CONTENTS) == 0) {
final ContentsEList elist = (ContentsEList) super.getContents();
final NotificationChain notifications = elist.basicAdd(eObject, null);
if (notifications != null && sendNotificationsOnLoad) {
notifications.dispatch();
}
}

if (isTrackingModification()) {
eObject.eAdapters().add(modificationTrackingAdapter);
}

Map map = getIntrinsicIDToEObjectMap();
if (map != null) {
String id = EcoreUtil.getID(eObject);
if (id != null) {
map.put(id, eObject);
}
}

// now also attach all ereferences with single values which are contained
for (Iterator it = eObject.eClass().getEAllReferences().iterator();
it.hasNext();) {
final EReference eref = (EReference) it.next();
if (!eref.isMany() && eObject.eGet(eref) != null) { // the ismanies are
handled differently
final Resource res = ((EObject) eObject.eGet(eref)).eResource();
if (res == null) { // attach it to this resource because it has no
other
final InternalEObject referedTo = (InternalEObject)
eObject.eGet(eref);
attached(referedTo);
}
}
}
}
--------------------------


2) org.eclipse.emf.teneo.resource.detachedHelper: (The NPE is immediately
thrown on hitting the eObject.eResource() line because eObject is null)
-----------------
/** Overridden to also support persistence specific id instead of single
emf id */
protected void detachedHelper(EObject eObject) {
// Begin Sundeep Addition
if (eObject == null) return;
//End Sundeep Addition
// support move to other resource
if (eObject.eResource() != this) {
removedEObjects.remove(eObject);
modifiedEObjects.remove(eObject);
loadedEObjects.remove(eObject);
newEObjects.remove(eObject);
return;
}

removedEObject(eObject);

Map map = getIntrinsicIDToEObjectMap();
if (map != null) {
String id = EcoreUtil.getID(eObject);
if (id != null) {
map.remove(id);
}
}

if (isTrackingModification()) {
eObject.eAdapters().remove(modificationTrackingAdapter);
}
}
----------------------

3)
org.eclipse.emf.teneo.resource.NonLoadingDiagnostician.doVal idateContents:
The NPE is thrown actually in
org.eclipse.emf.ecore.util.Diagnostician.validate(Diagnostic ian.java:107)
when called from the doValidateCOntents because "child" is null.

-----------------
protected boolean doValidateContents(EObject eObject, DiagnosticChain
diagnostics, Map context) {
List eContents = NonLoadingEContentsEList.create(eObject, true);
if (!eContents.isEmpty()) {
Iterator i = eContents.iterator();
EObject child = (EObject) i.next();
boolean result = validate(child, diagnostics, context);
while (i.hasNext() && (result || diagnostics != null)) {
child = (EObject) i.next();
// Begin Sundeep Addition
if (child != null) {
// End Sundeep Addition
result &= validate(child, diagnostics, context);
// Begin Sundeep Addition
}
// End Sundeep Addition
}
return result;
} else {
return true;
}
}
}
-----------------

4) org.eclipse.emf.teneo.EContainerRepairControl.setEResourceTo AlLContent

-----------------
public static void setEResourceToAlLContent(InternalEObject start,
Resource res) {
for (Iterator it =
start.eClass().getEAllStructuralFeatures().iterator(); it.hasNext();) {
final EStructuralFeature estruct = (EStructuralFeature) it.next();
if (estruct instanceof EReference) {
final EReference eref = (EReference) estruct;
if (eref.isMany()) {
final EList list = (EList) start.eGet(eref);
if (list == null)
continue;
if ((list instanceof PersistableEList) &&
!((PersistableEList)list).isLoaded()) {
continue;
}
if ((list instanceof PersistableFeatureMap) &&
!((PersistableFeatureMap)list).isLoaded()) {
continue;
}
for (int i = 0; i < list.size(); i++) {
final InternalEObject child = (InternalEObject) list.get(i);
// Begin Sundeep Addition
if (child != null) {
// End Sundeep Addition
if (child.eResource() == null) // no container
{
setResource(child, new ArrayList(), (Resource.Internal) res);
}
// Begin Sundeep Addition
}
// End Sundeep Addition
}
} else {
final InternalEObject child = (InternalEObject) start.eGet(eref);
if (child != null && child.eResource() == null) {
setResource(child, new ArrayList(), (Resource.Internal) res);
}
}
}
}
}

-----------------
Re: Sparse lists seem to cause havoc in Teneo 0.7.5 [message #125947 is a reply to message #125934] Sat, 14 June 2008 21:42 Go to previous message
Martin Taal is currently offline Martin TaalFriend
Messages: 5468
Registered: July 2009
Senior Member
Hi Sundeep,
Hmmm, although you provide a fair amount of information it is still difficult to say anything
specific about this. The only thing I can advice is to debug/log the cases that the eobject is null
and then try to backtrack to the query causing it. For example to log a special code in the places
where you now prevent the npe and then analyse the log to find the hibernate/sql query. Maybe there
are outer joins which result in null values (guessing here...).

Can you also post the npe? The one in the attached helper probably gives the easiest stacktrace (to
analyse).

gr. Martin

Sundeep Prakash wrote:
> Hello Martin,
> Thank you very much for devoting your time to address this issue. To
> answer your question, yes we definitely satisfy conditions 1 and 2 i.e.
> I believe the list is persisted as a foreign key from child to parent,
> and the list is mapped as a list with an index column. But I am quite
> sure condition 3 is not satisfied, i.e. do not remove the child without
> loading the parent. I believe that if we did, we would get sparse lists
> even for simple queries. We get sparse lists only when we have rather
> large queries with lots of join conditions, not on simple queries.
>
> Also, more detail as to the (now 4) places where I have seen NPEs (To
> prevent them, I have guarded them myself, see the code between "Begin
> Sundeep Addition" and "End Sundeep Addition" in each of the 4 methods
> below to see where the NPE occurred).
>
> Regards,
>
> Sundeep
>
> The four pieces of code from Teneo 0.7.5 follow:
>
> 1) org.eclipse.emf.teneo.resource.attachedHelper: (The NPE is
> immediately thrown on hitting the eObject.eContainer() line because
> eObject is null)
> ---------------------------
> protected void attachedHelper(EObject eObject) {
>
> // Begin Sundeep Addition
> if (eObject == null) return;
> // End Sundeep Addition
> // also attach the container
> if (eObject.eContainer() != null &&
> eObject.eContainer().eResource() == null &&
> !eObject.eContainmentFeature().isResolveProxies()) {
> attached(eObject.eContainer());
> }
>
> // a bit strange as an object can only be contained once but
> this can happen if someone
> // adds an object to a resource directly and then later add this
> same object as a child
> // to a container
> if (newEObjects.contains(eObject) ||
> loadedEObjects.contains(eObject))
> return;
>
> // Already belongs to another resource
> if (eObject.eResource() != null && eObject.eResource() != this) {
> return;
> }
>
> addedEObject(eObject);
>
> if (eObject instanceof InternalEObject && eObject.eResource() ==
> null) {
> setEResource((InternalEObject)eObject, false);
> }
>
> // only add an eobject to contents if it does not have a
> container or if the container // relation allows resolve proxies
> (container and contained can be in different resources)
> // and the load strategy is correct
> if ((eObject.eContainer() == null ||
> eObject.eContainmentFeature() == null ||
> eObject.eContainmentFeature().isResolveProxies()) &&
> !getSuperContents().contains(eObject) &&
> loadStrategy.compareTo(ADD_TO_CONTENTS) == 0) {
> final ContentsEList elist = (ContentsEList)
> super.getContents();
> final NotificationChain notifications =
> elist.basicAdd(eObject, null);
> if (notifications != null && sendNotificationsOnLoad) {
> notifications.dispatch();
> }
> }
>
> if (isTrackingModification()) {
> eObject.eAdapters().add(modificationTrackingAdapter);
> }
>
> Map map = getIntrinsicIDToEObjectMap();
> if (map != null) {
> String id = EcoreUtil.getID(eObject);
> if (id != null) {
> map.put(id, eObject);
> }
> }
>
> // now also attach all ereferences with single values which are
> contained
> for (Iterator it =
> eObject.eClass().getEAllReferences().iterator(); it.hasNext();) {
> final EReference eref = (EReference) it.next();
> if (!eref.isMany() && eObject.eGet(eref) != null) { // the
> ismanies are handled differently
> final Resource res = ((EObject)
> eObject.eGet(eref)).eResource();
> if (res == null) { // attach it to this resource because
> it has no other
> final InternalEObject referedTo = (InternalEObject)
> eObject.eGet(eref);
> attached(referedTo);
> }
> }
> }
> }
> --------------------------
>
>
> 2) org.eclipse.emf.teneo.resource.detachedHelper: (The NPE is
> immediately thrown on hitting the eObject.eResource() line because
> eObject is null)
> -----------------
> /** Overridden to also support persistence specific id instead of single
> emf id */
> protected void detachedHelper(EObject eObject) {
> // Begin Sundeep Addition
> if (eObject == null) return;
> //End Sundeep Addition
> // support move to other resource
> if (eObject.eResource() != this) {
> removedEObjects.remove(eObject);
> modifiedEObjects.remove(eObject);
> loadedEObjects.remove(eObject);
> newEObjects.remove(eObject);
> return;
> }
>
> removedEObject(eObject);
>
> Map map = getIntrinsicIDToEObjectMap();
> if (map != null) {
> String id = EcoreUtil.getID(eObject);
> if (id != null) {
> map.remove(id);
> }
> }
>
> if (isTrackingModification()) {
> eObject.eAdapters().remove(modificationTrackingAdapter);
> }
> }
> ----------------------
>
> 3)
> org.eclipse.emf.teneo.resource.NonLoadingDiagnostician.doVal idateContents:
> The NPE is thrown actually in
> org.eclipse.emf.ecore.util.Diagnostician.validate(Diagnostic ian.java:107)
> when called from the doValidateCOntents because "child" is null.
> -----------------
> protected boolean doValidateContents(EObject eObject,
> DiagnosticChain diagnostics, Map context) {
> List eContents = NonLoadingEContentsEList.create(eObject, true);
> if (!eContents.isEmpty()) {
> Iterator i = eContents.iterator();
> EObject child = (EObject) i.next();
> boolean result = validate(child, diagnostics, context);
> while (i.hasNext() && (result || diagnostics != null)) {
> child = (EObject) i.next();
> // Begin Sundeep Addition
> if (child != null) {
> // End Sundeep Addition
> result &= validate(child, diagnostics, context);
> // Begin Sundeep Addition
> }
> // End Sundeep Addition
> }
> return result;
> } else {
> return true;
> }
> }
> }
> -----------------
>
> 4) org.eclipse.emf.teneo.EContainerRepairControl.setEResourceTo AlLContent
>
> -----------------
> public static void setEResourceToAlLContent(InternalEObject start,
> Resource res) {
> for (Iterator it =
> start.eClass().getEAllStructuralFeatures().iterator(); it.hasNext();) {
> final EStructuralFeature estruct = (EStructuralFeature)
> it.next();
> if (estruct instanceof EReference) {
> final EReference eref = (EReference) estruct;
> if (eref.isMany()) {
> final EList list = (EList) start.eGet(eref);
> if (list == null)
> continue;
> if ((list instanceof PersistableEList) &&
> !((PersistableEList)list).isLoaded()) {
> continue;
> }
> if ((list instanceof PersistableFeatureMap) &&
> !((PersistableFeatureMap)list).isLoaded()) {
> continue;
> }
> for (int i = 0; i < list.size(); i++) {
> final InternalEObject child = (InternalEObject)
> list.get(i);
> // Begin Sundeep Addition
> if (child != null) {
> // End Sundeep Addition
> if (child.eResource() == null) // no container
> {
> setResource(child, new ArrayList(),
> (Resource.Internal) res);
> }
> // Begin Sundeep Addition
> }
> // End Sundeep Addition
> }
> } else {
> final InternalEObject child = (InternalEObject)
> start.eGet(eref);
> if (child != null && child.eResource() == null) {
> setResource(child, new ArrayList(),
> (Resource.Internal) res);
> }
> }
> }
> }
> }
>
> -----------------
>
>
>


--

With Regards, Martin Taal

Springsite/Elver.org
Office: Hardwareweg 4, 3821 BV Amersfoort
Postal: Nassaulaan 7, 3941 EC Doorn
The Netherlands
Cell: +31 (0)6 288 48 943
Tel: +31 (0)84 420 2397
Fax: +31 (0)84 225 9307
Mail: mtaal@springsite.com - mtaal@elver.org
Web: www.springsite.com - www.elver.org
Re: Sparse lists seem to cause havoc in Teneo 0.7.5 [message #619220 is a reply to message #125488] Sun, 08 June 2008 19:49 Go to previous message
Martin Taal is currently offline Martin TaalFriend
Messages: 5468
Registered: July 2009
Senior Member
Hi Sundeep,
Can you send me the stack trace with the npe? I am mainly interested in the exact line in the
attachedHelper and detachedHelper methods you get this exception. If you can also post the source
code that would be nice to.

If you think the cause is sparse lists then the following can result in null-entries in a list:
- A list is persisted as a foreign key from the child to parent (so not using a join table)
- The list is mapped as a list (so with an index column).
- The child is removed from the db without loading the parent.

As an example: assume an object p has a list of objects o1 and o2, in the db o1 has a foreign key to
p with index column 0, and o2 has a foreign key to p with index column 1. Then in a new session o1
is read and removed (from the db). Then the db has the record for p and o2 with index 1. If p is
read then o2 is placed in position 1 in the list and position 0 will have a null entry in the list.

Can this occur in this case?

gr. Martin

Sundeep Prakash wrote:
> Hello Martin,
> We have Teneo-0.7.5 in production in some customer sites. There is this
> problem that keeps cropping up, and while I cant share the exact
> details, I thought I would bring the essential problem to your attention
> so that you could consider fixing it in the 0.8 line, if you can figure
> out why exactly it is happening. I cant provide an easy test case
> without getting a ton of EMF models and DB data from the customer, and
> that wont be possible.
>
> Essential problem is that upon saving a Teneo resource, in these
> somewhat random cases (i.e. I cant characterize the Hibernate query that
> forms these resources very clearly), we get NPEs. The NPEs always occur
> in the following three methods:
> 1)
> org.eclipse.emf.teneo.resource.NonLoadingDiagnostician.doVal idateContents
> - The NPE doesnt actually happen here, but this method has a line
> "result &= validate(child, diagnostics, context);". The "validate" call
> to EMF Ecore does not like Null "child" objects. Question is - why is
> Teneo sending it nulls.
> 2) org.eclipse.emf.teneo.resource.attachedHelper
> 3) org.eclipse.emf.teneo.resource.detachedHelper
> Both of the above methods also NPE on getting Null objects.
> We have gotten around the problem by putting null checks in cases 2 and
> 3. But I dont exactly understand why the nulls come in the first place
> especially when the code is not expecting them. My guess is that
> Hibernate is perhaps returning sparse lists in its queries (i.e. some
> elements are null) and this creates trouble when you assemble EMF
> resources using these objects(?). Is this a possibility? If so, should
> you be guarding against such cases? Of course, if all of this is gone in
> 0.8, that's great (I havent been able to test these cases with 0.8
> because I need to migrate the problematic data).
>
> Thanks,
>
> Sundeep
>


--

With Regards, Martin Taal

Springsite/Elver.org
Office: Hardwareweg 4, 3821 BV Amersfoort
Postal: Nassaulaan 7, 3941 EC Doorn
The Netherlands
Cell: +31 (0)6 288 48 943
Tel: +31 (0)84 420 2397
Fax: +31 (0)84 225 9307
Mail: mtaal@springsite.com - mtaal@elver.org
Web: www.springsite.com - www.elver.org
Re: Sparse lists seem to cause havoc in Teneo 0.7.5 [message #619251 is a reply to message #125502] Fri, 13 June 2008 21:23 Go to previous message
Sundeep Prakash is currently offline Sundeep PrakashFriend
Messages: 14
Registered: July 2009
Junior Member
Hello Martin,
Thank you very much for devoting your time to address this issue. To
answer your question, yes we definitely satisfy conditions 1 and 2 i.e. I
believe the list is persisted as a foreign key from child to parent, and
the list is mapped as a list with an index column. But I am quite sure
condition 3 is not satisfied, i.e. do not remove the child without loading
the parent. I believe that if we did, we would get sparse lists even for
simple queries. We get sparse lists only when we have rather large queries
with lots of join conditions, not on simple queries.

Also, more detail as to the (now 4) places where I have seen NPEs (To
prevent them, I have guarded them myself, see the code between "Begin
Sundeep Addition" and "End Sundeep Addition" in each of the 4 methods
below to see where the NPE occurred).

Regards,

Sundeep

The four pieces of code from Teneo 0.7.5 follow:

1) org.eclipse.emf.teneo.resource.attachedHelper: (The NPE is immediately
thrown on hitting the eObject.eContainer() line because eObject is null)
---------------------------
protected void attachedHelper(EObject eObject) {

// Begin Sundeep Addition
if (eObject == null) return;
// End Sundeep Addition
// also attach the container
if (eObject.eContainer() != null && eObject.eContainer().eResource() ==
null &&
!eObject.eContainmentFeature().isResolveProxies()) {
attached(eObject.eContainer());
}

// a bit strange as an object can only be contained once but this can
happen if someone
// adds an object to a resource directly and then later add this same
object as a child
// to a container
if (newEObjects.contains(eObject) || loadedEObjects.contains(eObject))
return;

// Already belongs to another resource
if (eObject.eResource() != null && eObject.eResource() != this) {
return;
}

addedEObject(eObject);

if (eObject instanceof InternalEObject && eObject.eResource() == null) {
setEResource((InternalEObject)eObject, false);
}

// only add an eobject to contents if it does not have a container or if
the container
// relation allows resolve proxies (container and contained can be in
different resources)
// and the load strategy is correct
if ((eObject.eContainer() == null || eObject.eContainmentFeature() ==
null ||
eObject.eContainmentFeature().isResolveProxies()) &&
!getSuperContents().contains(eObject) &&
loadStrategy.compareTo(ADD_TO_CONTENTS) == 0) {
final ContentsEList elist = (ContentsEList) super.getContents();
final NotificationChain notifications = elist.basicAdd(eObject, null);
if (notifications != null && sendNotificationsOnLoad) {
notifications.dispatch();
}
}

if (isTrackingModification()) {
eObject.eAdapters().add(modificationTrackingAdapter);
}

Map map = getIntrinsicIDToEObjectMap();
if (map != null) {
String id = EcoreUtil.getID(eObject);
if (id != null) {
map.put(id, eObject);
}
}

// now also attach all ereferences with single values which are contained
for (Iterator it = eObject.eClass().getEAllReferences().iterator();
it.hasNext();) {
final EReference eref = (EReference) it.next();
if (!eref.isMany() && eObject.eGet(eref) != null) { // the ismanies are
handled differently
final Resource res = ((EObject) eObject.eGet(eref)).eResource();
if (res == null) { // attach it to this resource because it has no
other
final InternalEObject referedTo = (InternalEObject)
eObject.eGet(eref);
attached(referedTo);
}
}
}
}
--------------------------


2) org.eclipse.emf.teneo.resource.detachedHelper: (The NPE is immediately
thrown on hitting the eObject.eResource() line because eObject is null)
-----------------
/** Overridden to also support persistence specific id instead of single
emf id */
protected void detachedHelper(EObject eObject) {
// Begin Sundeep Addition
if (eObject == null) return;
//End Sundeep Addition
// support move to other resource
if (eObject.eResource() != this) {
removedEObjects.remove(eObject);
modifiedEObjects.remove(eObject);
loadedEObjects.remove(eObject);
newEObjects.remove(eObject);
return;
}

removedEObject(eObject);

Map map = getIntrinsicIDToEObjectMap();
if (map != null) {
String id = EcoreUtil.getID(eObject);
if (id != null) {
map.remove(id);
}
}

if (isTrackingModification()) {
eObject.eAdapters().remove(modificationTrackingAdapter);
}
}
----------------------

3)
org.eclipse.emf.teneo.resource.NonLoadingDiagnostician.doVal idateContents:
The NPE is thrown actually in
org.eclipse.emf.ecore.util.Diagnostician.validate(Diagnostic ian.java:107)
when called from the doValidateCOntents because "child" is null.

-----------------
protected boolean doValidateContents(EObject eObject, DiagnosticChain
diagnostics, Map context) {
List eContents = NonLoadingEContentsEList.create(eObject, true);
if (!eContents.isEmpty()) {
Iterator i = eContents.iterator();
EObject child = (EObject) i.next();
boolean result = validate(child, diagnostics, context);
while (i.hasNext() && (result || diagnostics != null)) {
child = (EObject) i.next();
// Begin Sundeep Addition
if (child != null) {
// End Sundeep Addition
result &= validate(child, diagnostics, context);
// Begin Sundeep Addition
}
// End Sundeep Addition
}
return result;
} else {
return true;
}
}
}
-----------------

4) org.eclipse.emf.teneo.EContainerRepairControl.setEResourceTo AlLContent

-----------------
public static void setEResourceToAlLContent(InternalEObject start,
Resource res) {
for (Iterator it =
start.eClass().getEAllStructuralFeatures().iterator(); it.hasNext();) {
final EStructuralFeature estruct = (EStructuralFeature) it.next();
if (estruct instanceof EReference) {
final EReference eref = (EReference) estruct;
if (eref.isMany()) {
final EList list = (EList) start.eGet(eref);
if (list == null)
continue;
if ((list instanceof PersistableEList) &&
!((PersistableEList)list).isLoaded()) {
continue;
}
if ((list instanceof PersistableFeatureMap) &&
!((PersistableFeatureMap)list).isLoaded()) {
continue;
}
for (int i = 0; i < list.size(); i++) {
final InternalEObject child = (InternalEObject) list.get(i);
// Begin Sundeep Addition
if (child != null) {
// End Sundeep Addition
if (child.eResource() == null) // no container
{
setResource(child, new ArrayList(), (Resource.Internal) res);
}
// Begin Sundeep Addition
}
// End Sundeep Addition
}
} else {
final InternalEObject child = (InternalEObject) start.eGet(eref);
if (child != null && child.eResource() == null) {
setResource(child, new ArrayList(), (Resource.Internal) res);
}
}
}
}
}

-----------------
Re: Sparse lists seem to cause havoc in Teneo 0.7.5 [message #619252 is a reply to message #125934] Sat, 14 June 2008 21:42 Go to previous message
Martin Taal is currently offline Martin TaalFriend
Messages: 5468
Registered: July 2009
Senior Member
Hi Sundeep,
Hmmm, although you provide a fair amount of information it is still difficult to say anything
specific about this. The only thing I can advice is to debug/log the cases that the eobject is null
and then try to backtrack to the query causing it. For example to log a special code in the places
where you now prevent the npe and then analyse the log to find the hibernate/sql query. Maybe there
are outer joins which result in null values (guessing here...).

Can you also post the npe? The one in the attached helper probably gives the easiest stacktrace (to
analyse).

gr. Martin

Sundeep Prakash wrote:
> Hello Martin,
> Thank you very much for devoting your time to address this issue. To
> answer your question, yes we definitely satisfy conditions 1 and 2 i.e.
> I believe the list is persisted as a foreign key from child to parent,
> and the list is mapped as a list with an index column. But I am quite
> sure condition 3 is not satisfied, i.e. do not remove the child without
> loading the parent. I believe that if we did, we would get sparse lists
> even for simple queries. We get sparse lists only when we have rather
> large queries with lots of join conditions, not on simple queries.
>
> Also, more detail as to the (now 4) places where I have seen NPEs (To
> prevent them, I have guarded them myself, see the code between "Begin
> Sundeep Addition" and "End Sundeep Addition" in each of the 4 methods
> below to see where the NPE occurred).
>
> Regards,
>
> Sundeep
>
> The four pieces of code from Teneo 0.7.5 follow:
>
> 1) org.eclipse.emf.teneo.resource.attachedHelper: (The NPE is
> immediately thrown on hitting the eObject.eContainer() line because
> eObject is null)
> ---------------------------
> protected void attachedHelper(EObject eObject) {
>
> // Begin Sundeep Addition
> if (eObject == null) return;
> // End Sundeep Addition
> // also attach the container
> if (eObject.eContainer() != null &&
> eObject.eContainer().eResource() == null &&
> !eObject.eContainmentFeature().isResolveProxies()) {
> attached(eObject.eContainer());
> }
>
> // a bit strange as an object can only be contained once but
> this can happen if someone
> // adds an object to a resource directly and then later add this
> same object as a child
> // to a container
> if (newEObjects.contains(eObject) ||
> loadedEObjects.contains(eObject))
> return;
>
> // Already belongs to another resource
> if (eObject.eResource() != null && eObject.eResource() != this) {
> return;
> }
>
> addedEObject(eObject);
>
> if (eObject instanceof InternalEObject && eObject.eResource() ==
> null) {
> setEResource((InternalEObject)eObject, false);
> }
>
> // only add an eobject to contents if it does not have a
> container or if the container // relation allows resolve proxies
> (container and contained can be in different resources)
> // and the load strategy is correct
> if ((eObject.eContainer() == null ||
> eObject.eContainmentFeature() == null ||
> eObject.eContainmentFeature().isResolveProxies()) &&
> !getSuperContents().contains(eObject) &&
> loadStrategy.compareTo(ADD_TO_CONTENTS) == 0) {
> final ContentsEList elist = (ContentsEList)
> super.getContents();
> final NotificationChain notifications =
> elist.basicAdd(eObject, null);
> if (notifications != null && sendNotificationsOnLoad) {
> notifications.dispatch();
> }
> }
>
> if (isTrackingModification()) {
> eObject.eAdapters().add(modificationTrackingAdapter);
> }
>
> Map map = getIntrinsicIDToEObjectMap();
> if (map != null) {
> String id = EcoreUtil.getID(eObject);
> if (id != null) {
> map.put(id, eObject);
> }
> }
>
> // now also attach all ereferences with single values which are
> contained
> for (Iterator it =
> eObject.eClass().getEAllReferences().iterator(); it.hasNext();) {
> final EReference eref = (EReference) it.next();
> if (!eref.isMany() && eObject.eGet(eref) != null) { // the
> ismanies are handled differently
> final Resource res = ((EObject)
> eObject.eGet(eref)).eResource();
> if (res == null) { // attach it to this resource because
> it has no other
> final InternalEObject referedTo = (InternalEObject)
> eObject.eGet(eref);
> attached(referedTo);
> }
> }
> }
> }
> --------------------------
>
>
> 2) org.eclipse.emf.teneo.resource.detachedHelper: (The NPE is
> immediately thrown on hitting the eObject.eResource() line because
> eObject is null)
> -----------------
> /** Overridden to also support persistence specific id instead of single
> emf id */
> protected void detachedHelper(EObject eObject) {
> // Begin Sundeep Addition
> if (eObject == null) return;
> //End Sundeep Addition
> // support move to other resource
> if (eObject.eResource() != this) {
> removedEObjects.remove(eObject);
> modifiedEObjects.remove(eObject);
> loadedEObjects.remove(eObject);
> newEObjects.remove(eObject);
> return;
> }
>
> removedEObject(eObject);
>
> Map map = getIntrinsicIDToEObjectMap();
> if (map != null) {
> String id = EcoreUtil.getID(eObject);
> if (id != null) {
> map.remove(id);
> }
> }
>
> if (isTrackingModification()) {
> eObject.eAdapters().remove(modificationTrackingAdapter);
> }
> }
> ----------------------
>
> 3)
> org.eclipse.emf.teneo.resource.NonLoadingDiagnostician.doVal idateContents:
> The NPE is thrown actually in
> org.eclipse.emf.ecore.util.Diagnostician.validate(Diagnostic ian.java:107)
> when called from the doValidateCOntents because "child" is null.
> -----------------
> protected boolean doValidateContents(EObject eObject,
> DiagnosticChain diagnostics, Map context) {
> List eContents = NonLoadingEContentsEList.create(eObject, true);
> if (!eContents.isEmpty()) {
> Iterator i = eContents.iterator();
> EObject child = (EObject) i.next();
> boolean result = validate(child, diagnostics, context);
> while (i.hasNext() && (result || diagnostics != null)) {
> child = (EObject) i.next();
> // Begin Sundeep Addition
> if (child != null) {
> // End Sundeep Addition
> result &= validate(child, diagnostics, context);
> // Begin Sundeep Addition
> }
> // End Sundeep Addition
> }
> return result;
> } else {
> return true;
> }
> }
> }
> -----------------
>
> 4) org.eclipse.emf.teneo.EContainerRepairControl.setEResourceTo AlLContent
>
> -----------------
> public static void setEResourceToAlLContent(InternalEObject start,
> Resource res) {
> for (Iterator it =
> start.eClass().getEAllStructuralFeatures().iterator(); it.hasNext();) {
> final EStructuralFeature estruct = (EStructuralFeature)
> it.next();
> if (estruct instanceof EReference) {
> final EReference eref = (EReference) estruct;
> if (eref.isMany()) {
> final EList list = (EList) start.eGet(eref);
> if (list == null)
> continue;
> if ((list instanceof PersistableEList) &&
> !((PersistableEList)list).isLoaded()) {
> continue;
> }
> if ((list instanceof PersistableFeatureMap) &&
> !((PersistableFeatureMap)list).isLoaded()) {
> continue;
> }
> for (int i = 0; i < list.size(); i++) {
> final InternalEObject child = (InternalEObject)
> list.get(i);
> // Begin Sundeep Addition
> if (child != null) {
> // End Sundeep Addition
> if (child.eResource() == null) // no container
> {
> setResource(child, new ArrayList(),
> (Resource.Internal) res);
> }
> // Begin Sundeep Addition
> }
> // End Sundeep Addition
> }
> } else {
> final InternalEObject child = (InternalEObject)
> start.eGet(eref);
> if (child != null && child.eResource() == null) {
> setResource(child, new ArrayList(),
> (Resource.Internal) res);
> }
> }
> }
> }
> }
>
> -----------------
>
>
>


--

With Regards, Martin Taal

Springsite/Elver.org
Office: Hardwareweg 4, 3821 BV Amersfoort
Postal: Nassaulaan 7, 3941 EC Doorn
The Netherlands
Cell: +31 (0)6 288 48 943
Tel: +31 (0)84 420 2397
Fax: +31 (0)84 225 9307
Mail: mtaal@springsite.com - mtaal@elver.org
Web: www.springsite.com - www.elver.org
Previous Topic:Resource.load is emptying all resources
Next Topic:[Teneo] Can't persist reference when EOpposite is set.
Goto Forum:
  


Current Time: Fri Apr 19 21:21:32 GMT 2024

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

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

Back to the top