0

i have requirement where i am passing list of accountuuids to method 1.If contact with same accountname not present then create new contat call as shadow contact 2.if contact with same accountname present then update the shadow contact to true also link the contact to account

below is my code but getting soql limit reached and also not updating contact to shadow.

can some one please help to see what is the issue any other way to do is my logic is correct to check if contact with account name is available?

public class AccountContactCreation {

public static void contactOperation(set<string> accountuuids){
    string accName ='';
    list<contact>conUpdate = new list<contact>();
    list<contact> conInsert = new list<contact>();
    List<Account> accList = new list<account>();
    accList =[select id,name from account where AccountUUID__c in:accountuuids ] ;
    set<string> names = new set<string>();
    for(account acc:accList) {
        names.add(acc.name);
    }
    List<contact> conList = [select id,name,Shadow_Contact__c,firstname,lastname from contact ];
    map<string,contact> conMap = new map<string,contact>();
    for(contact con:conList) {
        conMap.put(con.lastname,con);
    }
    for(account acc:accList) {
        for(contact con:conList) {
            if(acc.name == con.lastname){ 
                if(con.Shadow_Contact__c == false) {
                    contact cons = new contact();
                    cons.id = con.id;
                    cons.Shadow_Contact__c = true;
                    cons.accountid = acc.id;
                    conUpdate.add(cons);
                }
                else {
                    contact cons = new contact();
                    cons.id = con.id;
                    con.accountid = acc.id;
                    conUpdate.add(cons);    
                }
            }

        }


    }
    for(account acc:accList){
        if(!conMap.containskey(acc.name)){
            contact cons = new contact();
            cons.accountid = acc.id; 
            cons.lastname =acc.name;
            cons.Shadow_Contact__c = true;
            conInsert.add(cons);
        }
    }
    if(conUpdate.size()>0){
        system.debug('conUpdate--->'+conUpdate);
        update conUpdate;
    }
    if(conInsert.size()>0) {
        insert conInsert;
    }

}

}

1
  • Aside from the nested loop where you're doing if(acc.Name == con.LastName) (consider using Maps instead, much better for the CPU limit), I don't see anything problematic. Governor limits are cumulative throughout a transaction, so this code is just what's putting you over the limit. The actual issue lies elsewhere, and you should spend some time digging through your other code and debug logs to identify where the real issue is.
    – Derek F
    Apr 27 '20 at 11:22
1

You have a couple things that are probably causing issues for you here, but its hard to say definitively without knowing more about your org. Keep in mind the limits defined by Salesforce. Here is where I would start:

  1. Your query for contacts is: List<contact> conList = [select id,name,Shadow_Contact__c,firstname,lastname from contact ];

This is going to return every contact you have in your org which is going to be a potentially very large list (probably?). In reality, you are only interested in certain contacts, so you should update your query to include a WHERE clause to check the last name. Something like this: List<contact> conList = [select id,name,Shadow_Contact__c,firstname,lastname from contact WHERE lastname IN :names];

  1. The reason #1 matters, is because you are then using this list in a nested for loop. for(account acc:accList) { for(contact con:conList) {

So lets say you passed in 100 account records to this method. That means you are effectively looping through every single contact you have....100 times. Considering there could be millions of contacts in your org, this is very long running. Solving #1 will make this comparison much more manageable.

  1. You should use upserts in this scenario. It will save you needing to maintain separate lists for update and inserts, and also allow you to make a single dml statement.

  2. Consider using Maps a bit more - I see you've already used them in some places, but I'd suggest looking at seeing if you can also use them for your accounts. It seems like the two fields on accounts you are interested in are Id and Name, so using a map with those values might help improve execution time, although you may need to contend with duplicative Name values if thats a thing for your org.

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.