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
SF Beginner 2019SF Beginner 2019 

accountcontact issue

Issue is that sometimes it deletes sometime it doesn't delete or update.
 
global class AccountContactTriggerHandler implements Database.Batchable<sObject>
{
    List<AccountContactRelation> ListtoInsert = new List<AccountContactRelation>();
    Set<accountContactRelation> ListToDelete = new Set<accountContactRelation>();
    Map<String, Account> accCodeMap = new Map<String,Account>();
    map<string,Contact> contactAccountMap = new map<string, Contact>();
    String query = 'Select Id,Name,License_ID__c FROM Account WHERE License_ID__c != null AND IsPartner = true AND License_ID__c LIKE \'__\'';
    final String CLSSNAME = 'AccountContactTriggerHandler';
 
    global Database.QueryLocator start(Database.BatchableContext bc)
    {
        return Database.getQueryLocator(query);
    }
    
    global void execute(Database.BatchableContext bc,List<Account> batch){
        try{
            for(Account a : batch)
                accCodeMap.put(a.License_ID__c, a);

            for (Contact c : [Select ID, Name, Accountid, Person_ID__c, ABS_Person_ID__c, (SELECT AccountId, ContactId FROM AccountContactRelations) from Contact WHERE (ABS_Person_ID__c != null AND ABS_Person_ID__c LIKE '__') OR (Person_ID__c != null AND Person_ID__c LIKE '__')]){
                Set<String> acrIdList =new Set<String>();
                List<AccountContactRelation> acrList = c.AccountContactRelations;
                for(AccountContactRelation acrId : acrList){
                    contactAccountMap.put(acrId.AccountId, c); // Used for deleting code soql
                    acrIdList.add(acrId.AccountId);
                }

                Account a, a2;
                if(c.Person_ID__c != null)
                    a = accCodeMap.get(c.Person_ID__c);
                if(c.ABS_Person_ID__c != null)
                    a2 = accCodeMap.get(c.ABS_Person_ID__c);
                
                if(a != null && a2 != null && a == a2){
                    if(!acrIdList.contains(a.Id)){
                        if(c.Person_ID__c == a.License_ID__c){
                            AccountContactRelation   acr =  new AccountContactRelation();
                            acr.AccountId = a.id;
                            acr.contactId = c.Id;
                            ListtoInsert.add(acr);
                        }
                    }
                }
                else {
                    // Checks if the AccountContactRelations already connected to the Contact
                    if(a != null){
                        if(!acrIdList.contains(a.Id)){
                            if(c.Person_ID__c == a.License_ID__c){
                                AccountContactRelation   acr =  new AccountContactRelation();
                                acr.AccountId = a.id;
                                acr.contactId = c.Id;
                                ListtoInsert.add(acr);
                            }
                        }
                    } 
                    
                    if(a2 != null){
                        if(!acrIdList.contains(a2.Id)){
                            if(c.ABS_Person_ID__c == a2.License_ID__c){
                                AccountContactRelation   acr =  new AccountContactRelation();
                                acr.AccountId = a2.id;
                                acr.contactId = c.Id;
                                ListtoInsert.add(acr);
                            }
                        }
                    }
                }                
            }
            insert ListtoInsert;
            //loop only the accounts that are related/connected to AccountContactRelation Object
            map<string,Account> accountMap = new map<string, Account>();
            for(Account Acc: [SELECT id, Name, License_ID__c FROM Account WHERE Id =: contactAccountMap.keySet()])
            {
                accountMap.put(Acc.Id,acc);
            }
            //loop the AccountContactRelation to get the records where isDirect is not true
            for(AccountContactRelation AccountConDelete : [SELECT Id, AccountId, ContactId FROM AccountContactRelation WHERE Accountid =: contactAccountMap.keySet() AND isDirect != TRUE])
            {
                Account acc = accountMap.get(AccountConDelete.AccountId);
                contact con = contactAccountMap.get(AccountConDelete.AccountId);
                if(acc.License_ID__c != con.Person_ID__c && acc.License_ID__c != con.ABS_Person_ID__c)
                {
                    ListToDelete.add(AccountConDelete);    
                }
            }

            System.debug('TO BE DELETED: '+ListToDelete);  
            List<AccountContactRelation> AccountConNew = new List<AccountContactRelation>();
            for (AccountContactRelation acr : ListToDelete)
                AccountConNew.add(acr);
            
            delete AccountConNew;
        }																				
        catch(Exception e){
            
        }
    }	
    
    global void finish(Database.BatchableContext bc)
    {
        //DoNothing.
    }
}

 
SwethaSwetha (Salesforce Developers) 
HI, Do you see any error message when this trigger handler doesn't delete or update the records? Thanks
SF Beginner 2019SF Beginner 2019
right now when updating I'm getting Too many query rows: 50001
SwethaSwetha (Salesforce Developers) 
HI,
The error you are seeing is because of the governor limit (https://developer.salesforce.com/docs/atlas.en-us.salesforce_app_limits_cheatsheet.meta/salesforce_app_limits_cheatsheet/salesforce_app_limits_platform_apexgov.htm) enforced on the query. The total number of records retrieved by SOQL queries is 50,000. If it exceeds the limit you will see the Too many query rows: 50001 error.

You need to setup debug logs to Identify the Soql with aggregation which is contributing to this limit and then fix it. Track the output of each soql : not just the whole soql but the result of inner queries as well.

I also see that you are not using optimized SOQL queries in your AccountContactTriggerHandler class. You need to make the SOQL queries selective. Example: License_ID__c != null does not make your query selective. Instead, use License_ID__c ='abc','pqr'

See articles: https://help.salesforce.com/articleView?id=000325247&language=en_US%C2%A0&type=1&mode=1

https://help.salesforce.com/articleView?id=000325257&language=en_US&type=1&mode=1

The below links will give a better understanding of the troubleshooting approach of scenarios with same error
https://salesforce.stackexchange.com/questions/105609/system-limitexception-too-many-query-rows-50001-even-though-soql-has-limit-10

https://salesforce.stackexchange.com/questions/40916/too-many-query-rows-50001

https://stackoverflow.com/questions/9984349/limitexception-too-many-query-rows-50001-from-with-count-aggregate-function

Hope this helps you. Please mark this answer as best so that others facing the same issue will find this information useful. Thank you