+ Start a Discussion
astroastro 

how to check if a record exists without hitting null exception?

I'm writing a trigger in which I need to test if a record already exists in sf before I can proceed.

 

currently I am using this method:

 

if([select count() from account where id = :trigger.new[i].ParentId] > 0) {}

 

however this is not very governer limit friendly.  In the past I've tried using the isNull method wrapped around a try{ } catch  but that returned a null pointer exception (or whatever the equiv. is called in sf, I forget at the moment.

 

i have tried to use

if([select count() from account where id in :accIds] > 0){}

 

but as I understand, this statement works like this:  it will return as many  account records as there are  matching acound id's in thet set.  I just want to know if ONE particular account is in the set.

 

I hope that was clear.  If you  need any further explanation from me just let me know and I'll do my best to provide!

 

Best Answer chosen by Admin (Salesforce Developers) 
WhyserWhyser

Two ideas

 

1) instead of doing a select count() statement, why don't you do this instead

if( [select id from account where id = :trigger.new[i].ParentId].size() > 0 ) {}

This way you won't run into a null point exception because you're treating the results like a list instead of a single object returned (in your case, an integer returned)

 

2) Maybe do a big query that has all the accounts and store it into a map

Map< Id, Account > accMap = [select id, otherfields from Account where id in :accIds];

Now to see if an account exists, you can do this

if ( accMap.containsKey( a_certain_Account_Id ) == true ) {}

All Answers

WhyserWhyser

Two ideas

 

1) instead of doing a select count() statement, why don't you do this instead

if( [select id from account where id = :trigger.new[i].ParentId].size() > 0 ) {}

This way you won't run into a null point exception because you're treating the results like a list instead of a single object returned (in your case, an integer returned)

 

2) Maybe do a big query that has all the accounts and store it into a map

Map< Id, Account > accMap = [select id, otherfields from Account where id in :accIds];

Now to see if an account exists, you can do this

if ( accMap.containsKey( a_certain_Account_Id ) == true ) {}

This was selected as the best answer
astroastro

Thank you for responding Whyser.  2 very great ideas.  I can't use the first because it's not very gov. limit friendly :(

 

the 2nd one was very interesting.  What I did was have 2 extra maps in my trigger which contained the id's of ALL accounts and ALL of another type of customer object.

 

then I used your map.containsKey suggestion to check if the id was in the map.

 

in using this approach I have one query per trigger.new instance which is excellent!

 

However, would this be a viable solution in a production environment with possibly thousands of accounts/custom objects?  Do governer limits care that I am making a call such as [select id from accounts];?

 

if that type of statement is okay (I only use it once to put them into a map at the beggining of the trigger) than this has definitely solved my problem!

 

Thank's again for the help :) 

WhyserWhyser

You may run into problems if that is the case.

 

Maps can only contain up to 1,000 elements, and will throw an exception if you exceed this amount.

If this code is being executed in a trigger, you can only return 1,000 rows of data before you hit another governer limit.

 

Check out the governer limits here
http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_gov_limits.htm

 

If you're running this in a trigger, I don't see how running the code

if( [select id from account where id = :trigger.new[i].ParentId].size() > 0 ) {}

will run into governer limits. Unless you think that you will be updating or inserting more than 20 objects at the same time. That query will be run once per object updated/inserted, and the limit is 20 SOQL statements per trigger. Once you finish running that trigger, and if a new trigger runs, that will reset the limit back to 20 again.

 

astroastro

I've implemented the [query].size > 0 method you've referenced and I believe that makes my trigger as efficient as it possibly can be.

 

 

 

I'll just give them the limitation that they can only insert/update 20 objects at one time, but I guess with a trigger that would be the most you can ever get to in any case since it's a govorner limit.  

 

Thank's Whyser for your help and insight.  I've learned alot about how to create more efficient apex over the course of this.  You've been extremely helpful and I can only hope to offer you some assistance if your ever in need!