7

I have checked many posts but still not clear. A SOQL query returns a list but if SOQL finds no records then it will return an empty list or it will be null?

When should i go for isEmpty check or when for null check?

Thanks

1

3 Answers 3

14

The straight SOQL accounts = [select id, .. from Account ...]

always returns a list

You can usually avoid even having to test for list empty by coding your methods to accept lists as arguments and otherwise use for loop processing as in

for (Account a: accounts) { // if accounts is empty, loop does nothing
    // do work
}

someReturnType myMethod(Account[] accounts) {
   for (Account a: account) {
      // do work
   }
}

Otherwise use accounts.isEmpty() or accounts.size() == 0

testing for null is unnecessary in a well-designed application that uses lists and maps as the core internal data structures. Personally, if I ever get a null value for a list, I prefer the null exception to occur during unit testing as it means I didn't design my code correctly to operate with lists throughout (or I forgot to init a list to empty).

N.B.

For DML, you never need to test for list empty as SFDC will do nothing if passed an empty list

Use:

update accounts; // does not burn a DML limit if list is empty

Don't use (wastes a line of code):

if (!accounts.isEmpty())
   update accounts;
5
  • Great!! but in the last scenario, suppose i am adding some elements to list using add method after some processing on data and finally i need to insert this list. In this case also SFDC will do nothing if passed an empty list?
    – R Suri
    Commented Jan 7, 2017 at 16:32
  • that is correct; SFDC DML methods accept lists as arguments and if list is empty, the DML statement simply returns and does not consume any limits
    – cropredy
    Commented Jan 7, 2017 at 16:34
  • OK thanks!! one last Question, In what case we can get a null list? Or when should we check for NULL on list?
    – R Suri
    Commented Jan 7, 2017 at 16:39
  • 1
    @RamanSuri No SOQL query will return a NULL list. So you'd just check for NULL if other code generated the list for you, say from an apex method you didn't code. As @cropredy mentioned in his answer, if you do generate List or Map, don't return NULL, return an empty one so that the for ( Account a : accounts ) idiom works regardless. Hope that helps!
    – Doug Ayers
    Commented Jan 8, 2017 at 0:04
  • @RamanSuri if you ever study the fflib Separation of Concerns GitHub library, you'll see that some of the best coders in the business pass lists around from method to method.
    – cropredy
    Commented Jan 8, 2017 at 0:19
7

Generally speaking, null values should be rare, and you should treat them as such. The results of a query always results in a list, even though it may be an empty list. Querying a checkbox field from the database will always be true or false, never null. Calling XmlNode.getChildElements() will never return null, but may return empty lists.

There are a few rare exceptions when you do need to check for null values. For example, when you make a variable transient, its not stored in the view state, so you usually need to implement lazy loading by checking for null first, and when you bind to a multi-select picklist, the list will always be either null or non-empty.

These are the exceptions to the rule, and you should learn them. Whenever you declare a list of your own, you should always assign a non-null value to it, which may be either a new list, or a list generated from a query. You should prefer to initialize those lists in a constructor, so that all your initialization code is in one place.

Generally speaking, when I use a method I'm not familiar with, I try calling it with a few different parameters to see if I can get a null value back instead of a list. I test it independently to verify its behavior. If it doesn't return a null, then I presume it never will. Just remember that most of the API avoids returning null values, or has a way to check beforehand. Most of the best design patterns for code avoid nulls using various techniques. As you gain experience, you'll learn those rare times when you must check for null, and find ways to code structures to reduce the null checks you need to make.

4
  • 1
    the one exception here is when you use "getSObjects" on a subquery that was empty it will return null.....Found that out the hard way.
    – Eric
    Commented Jan 7, 2017 at 20:57
  • @Eric I found that out the hard way too this week. Blasted getSObjects will return the dreaded null like no tomorrow.
    – Doug Ayers
    Commented Jan 8, 2017 at 0:05
  • @Eric yeah - I forgot about that one; my code even has a comment next to the null check as to why I had to insert the conditional so I didn't remove it in some future hygiene cycle
    – cropredy
    Commented Jan 8, 2017 at 0:17
  • 1
    @Eric Yeah, the problem is the SObject object. It has magical properties as long as you're still in "SObject land", which happens to operate as a null coalescing operator. For example, User u = [SELECT Manager.Manager.Manager.Id FROM User WHERE Id = :UserInfo.getUserId()]; System.debug(u.Manager.Manager.Manager.Id) won't crash, even if the user has no manager. The dynamic methods don't get that same protection. Like I said, there's some rare occurrences where you do have to watch out, but generally nulls are uncommon.
    – sfdcfox
    Commented Jan 8, 2017 at 6:41
-4

The best way is to keep a check on list size and null check both. Here is an example -

 List<Account> accList = [select id,name from account where name='test'];

 if(accList.size()>0 && accList!=null){
      //make things happen!!
    }
1
  • 10
    f the null check was needed (it isn't in this case) it would need to come before the size check to avoid an NPE.
    – Keith C
    Commented Jan 7, 2017 at 17:21

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .