function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Adam FranklinAdam Franklin 

SOQL Query in Trigger returns Null. Returns with values in the query editor

Hi,

I was working on bulkifying a trigger that I'm writing and found another trigger (not mine!) that is breaking when I run my bulk tests.

I want to re-write it, but I'm finding that I cannot get the SOQL query in the trigger to return any results.

Here is the original trigger:
 
trigger UpdateAccountContactL1 on Case (before insert) {

    for(Case c : Trigger.new){    
        // Set profile IDs to exclude
        Set<Id> proIds = new Set<Id>{'00ea0000001p149', '00ea0000001p15L', '00ea0000001p14A'};       
        //Only process changes for Support record type with Account Name and Contact Name fields are blank        
           if(c.RecordTypeId == '012a00000018Ens' &&  (c.AccountId == null || c.ContactId == null)) {
                  // Get profile ID of Case Owner if Owner is not a Queue
                    User u = [SELECT ProfileId FROM User WHERE Id = :c.OwnerId]; 
                    // Process Account and Contact update if the User is one of the L1 profiles
  
            if(proIds.contains(u.ProfileId)){
                 List<Account> accList = [SELECT Id FROM Account WHERE Name = 'Generic Supplier'];         
                List<Contact> conList = [SELECT Id FROM Contact WHERE Name = 'Supplier Issue'];
                      c.AccountId = accList.isEmpty() ? null : accList[0].Id;
                     c.ContactId = conList.isEmpty() ? null : conList[0].Id;
            }
        }
    }
}

And here is what I've tried to rewrite it to:
 
trigger UpdateAccountContactL1 on Case (before insert) {     
	//Get record type ID
    String rt;
    List<RecordType> rts = [Select Id, Name FROM RecordType Where Name = 'Support' limit 1];
    if(rts.isEmpty()==false){
        rt = rts[0].id;
    }
  
    //List of users where this could apply.. goes against 
    List<User> t1Agents = [SELECT id, ProfileId from User where User.Profile.Name like '%Support Tier 1%'];
    Set<Id> agents = new Set<Id>(); 
    if(t1Agents.isEmpty()==false){
        for(User agent: t1Agents){
           agents.add(agent.id); 
        }
    }
   
    // Set ids to assign
        String accId;
       	String conId;
    	 List<Contact> cons = [Select Id,  AccountId From Contact WHERE Contact.Name = 'Supplier Issue'  AND Account.Name = 'Generic Supplier'];
    	if(cons.isEmpty()==false){
        System.debug(cons[0]);
        accId = cons[0].AccountId;
        conId = cons[0].id
         }
  
    for(Case c : Trigger.new){
        
       if(c.RecordTypeId == rt &&  (c.AccountId == null || c.ContactId == null)) {
            // Get profile ID of Case Owner if Owner is not a Queue
              
            // Process Account and Contact update if the User is one of the Tier 1 profiles
           if(agents.contains(c.OwnerId)){
                c.AccountId = accId;
                c.ContactId = conId;
              }
        }
    }
}

But what I'm seeing is that the List<Contact> cons =[].....   doesn't populate.   Why would this happen?   What can I do about it?

If i run in Execute anonymous - it works.  Same with Just entering the query in the query editor.   
List<Contact> cons = [Select Id,  AccountId From Contact WHERE Contact.Name = 'Supplier Issue'  AND Account.Name = 'Generic Supplier'];
System.debug(cons);

 
Best Answer chosen by Adam Franklin
pconpcon
Are you trying to run this in a test?  If so, you have to create the account first.  Post API version 24, all real-world data is no longer accessible to tests without the seeAllData [1] flag (which you should almost never use).

[1] http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_testing_seealldata_using.htm

All Answers

pconpcon
Are you trying to run this in a test?  If so, you have to create the account first.  Post API version 24, all real-world data is no longer accessible to tests without the seeAllData [1] flag (which you should almost never use).

[1] http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_testing_seealldata_using.htm
This was selected as the best answer
Adam FranklinAdam Franklin
Hi pcon,  Yes I was trying to run in a test.

That's a good point about the data being hidden.   I decided to create an account and contact in my test code to see if that made a difference, and it seemed to.   What surprised me was that other queries (User,Record Type) seemed to populate without issue.    So while I was able to get around that, it seems like maybe it isn't consistent.  

Thanks for your input.  I'm still relatively new to writing triggers, so I'm trying to make sure I develop good habits! 
pconpcon
Great, glad you got that sorted out.  The proper way to do the testing is to build up all of your test data for every test and then test your functionality.  There are a couple of objects [1] that you can reach at anytime.  I would recommend however that some of these (Users in particular) you create as part of your setup for your test anyway.  This is because if you rely on a specific user, that User may be deactiviated, renamed, etc and could break your tests.

If you want some ideas on best practices, I'd recommend checking out sfdc99 [2] or my talk on testing [3].  Also, if you were to classify [4] the trigger above, this would give you some greater flexibility for moving things like 'Generic Supplier' out to a static class level variable that you could use / overwrite in your tests.

If you do not mind, please choose the previous answer as the "best answer" so that it can help people in the future and so that it removes it from the unanswered questions pool.

[1] http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_testing_data_access.htm
[2] http://sfdc99.com/
[3] http://pcon.github.io/presentations/testing/
[4] http://blog.deadlypenguin.com/blog/2012/02/13/classifying-triggers-in-salesforce/
Adam FranklinAdam Franklin
Thanks for the excellent information and help.  It's always easier to build good habits than try to break bad ones, so this is great and very useful.