2

So, in my other post, I figured out for myself how to dynamically transverse SObject fields in Apex.

But within the context of my work, there is a problem with the solution as it currently stands:

private static String transverse  (Case countryCase, String csvFieldName) {
SObject      currentSObject = countryCase;
String       fieldPath      = csvFieldName;

while (fieldPath.contains('.'))
{
    List<String> pathPartList   = fieldPath.split ('[.]', 2);

                 currentSObject = (SObject) currentSObject.getSobject(pathPartList[0]);
                 fieldPath      = pathPartList[1];
}

return (String) currentSObject.get(fieldPath);

Not only am I trying to dynamically transverse the sObject (e.g. Case), but I have previously dynamically queried it.

So (for a simple example), I've retrieved from custom settings values which build an array which results in a query like:

SELECT id, subject, contact.lastName, contact.firstName FROM Case WHERE ...

Whereas the transverse function works fine in a context like:

 Case currentCase = getCase();
 currentCase.contact = getContact(caseContact.id);
 transverse(currentCase, 'Contact.lastName');

If/when/as I have not built up the Contact that way -- but rather just queried some fields while querying Case -- the results is a null-pointer exception because even though SFDC has a value for currentCase.Contact.LastName, it does not have a value for just currentCase.Contact.

While I could transform my original list of fields into several subsets, then query each SObject individually, and reassemble my case list, I'm wondering if there is any simpler solution (one which doesn't require multiple SOQL queries, conditional logic, and mapping).

  • I'm a little confused. Are you saying that when you actually make the SOQL query (or Database.query(...)), and attempt to use the transverse method, that you are getting null? I just ran a test in the dev console using the query SELECT Id, Contact.FirstName FROM Case and did not receive a null pointer. Are you confident your query is correct? – Andrew Monshizadeh May 26 '14 at 18:58
  • That is what I am saying. Testing confirmed that if I try to get the value of Case.Contact.FirstName directly, the value is non-null. – Brian Kessler May 27 '14 at 5:37
1

Seems to me you need to check if the currentSObject that is set by getSobject() is null before trying to get the child field from it.

This will occur if the relationship from the parent to child object is undefined. I.e. The Case doesn't have a Contact set.

Revise the loop to:

while (fieldPath.contains('.'))
{
    List<String> pathPartList   = fieldPath.split ('[.]', 2);

                 currentSObject = (SObject) currentSObject.getSobject(pathPartList[0]);
                 if (currentSObject == null) { return null; }
                 fieldPath      = pathPartList[1];
}
| improve this answer | |
  • I tried including Contact.id in my dynamic SOQL query, but transverse() still failed with a null-pointer exception at return (String) currentSObject.get(fieldPath); Further inspection showed the value of currentSObject was still, and therefore still causing the error. – Brian Kessler May 27 '14 at 5:42
  • @BrianKessler "the value of currentSObject was still," - sorry, I don't follow that. Do you mean it wasn't null? Try adding a System.assert(currentSObject != null); before the return statement. – Daniel Ballinger May 27 '14 at 8:31
  • Sorry, got distracted, mid sentence. I mean the value of currentSObject was still null. Being null, I can't get firstName from it. I'd like to figure out a way for it not to be null without making the whole operation a lot more complicated. – Brian Kessler May 27 '14 at 9:40
  • @BrianKessler currentSObject being null suggests to me that there is no Contact record for that Case, or that the current user doesn't have access to it. Is your Apex class using with sharing? – Daniel Ballinger May 27 '14 at 19:51
  • on further reflection and examination, it turns out you are correct: the Case had no contact. It seems that SFDC gives currentCase.contact.lastName a pass instead of an NPE when it is read in as such from a SOQL query, which confused me. – Brian Kessler May 28 '14 at 12:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.