Stat Tracker

Monday, February 14, 2011

Infamous Rookie Error : System.QueryException: List has no rows for assignment to SObject

System.QueryException: List has no rows for assignment to SObject

I see this error time and time again in the developer boards, when I'm working with junior developers, or working with developers who are new to the platform. So I figured I'd write up a quick post about it and how to solve it. Lets say I have a trigger or controller or any Apex code which needs to execute a SOQL query.

For the purpose of this example, lets just say I'm going to query on Account Name. In this example, I expect all my Accounts to have unique names. Below is how a junior developer may write this query:

Example Problematic Apex Code:

Account lateAccount = [Select Id, Name from Account where Name =: inputName limit 1];

The problem? If this SOQL executes and there are no matches for inputName, than this statement will throw the System.QueryException. Why? Behind the scenes I think Apex is trying to take a result from List in memory (The list of results from SOQL) and convert the first row into a SOBject for assignment to your variable. Since there are 0 results, it throws the exception.

There are 2 ways to solve this:

1. You can wrap this in a Try/Catch block like so:

Account lateAccount = null;
try{
      lateAccount = Account lateAccount = [Select Id, Name from Account where Name =: inputName limit 1];}
Catch(Exception e)
{ system.debug('There was an exception, but we can just set the lateAccount to null and continue on....);}

2. You can store the results in a List<SObject> instead of just an SObject and grab the first result like so:

Account lateAccount = null;
List<Account> resultAccounts = [Select Id, Name from Account where Name =: inputName limit 1];
if(resultAccounts.size() > 0){lateAccount = resultAccounts.get(0);} 

Its as simple as that. What method do I prefer? Personally, I like storing my results in Lists. Why? Well I usually already have try/catch logic to handle exceptions, and nesting additional try/catches can get a bit bulky. Its just a preference is all. Both approaches work perfectly fine. And depending on how your write your code, it may be preferable to do the Try/Catch approach. Its really up to the developers own taste.

Bottom Line - Its an easy problem to solve if you know the details, and now you know!


And knowing is half the battle!