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
Sunil NandipatiSunil Nandipati 

Merge Failed - Contact - While comparing records with LastModifiedDate

I tested the merge from my developer console and it works

Contact FirstContact = [Select Id from Contact where Id = '003L000000Xoxxxxxx'];
Contact SecondContact = [Select Id from Contact where Id = '003L000000Xoyyyyyy'];
merge FirstContact SecondContact;

But when I use the code I wrote (Class -> Method) and try to execute it from the Developer console i get this error

System.DmlException: Merge failed. First exception on row 0 with id 003L000000Xoxxxxxx; first error: INVALID_FIELD_FOR_INSERT_UPDATE, Unable to create/update fields: LastModifiedDate. Please check the security settings of this field and verify that it is read/write for your profile or permission set.: [LastModifiedDate]

-------------------Code here------------------------

public with sharing class CleanDuplicateContacts {

    public static void MergeDupes ()
    {
        // Gather all Emails which have dupes first
        List<AggregateResult> aggrResult = [Select Email from Contact group by Email having count(Id) > 1];
        System.Debug('Number of Emails with Duplicates - ' + aggrResult.size());
        List<String> dupeEmails = New List<String>();
        
        for(AggregateResult ar:aggrResult)
        {            
            // accountIds.add((ID)results.get('accountId'));
            System.Debug('Email from Aggr Result - ' + (String)ar.get('Email'));
            dupeEmails.add((String)ar.get('Email'));
        }
        
        // Get all the record Details of the records with the above Emails
        List<Contact> lstContacts = [Select Id, Email, EXTERNAL_ID__c, Email_Subscriptions__c, Contact_Source__c, EMail_Preferences_Last_Modified_Date__c, LastModifiedDate 
                                                from Contact Where Email in :dupeEmails Order by Email, EMail_Preferences_Last_Modified_Date__c desc];
        System.Debug('Records to Work on Now - ' + lstContacts.size());
        //    List<Contact> updContacts = New List<Contact>();
        
        Contact FirstContact = New Contact();
        Contact SecondContact = New Contact();
        Contact WinContact = New Contact();
        
        String Temp_EXTERNALID;
        String Temp_EmailSubscriptions;
        String Temp_ContactSource;
        
        for(Integer cnt = 0; cnt < lstContacts.size(); cnt++)
        {
            System.Debug('Inside For Loop with Counter - ' + cnt);
            FirstContact = lstContacts.get(cnt);
            SecondContact = lstContacts.get(cnt+1);
            
            if(FirstContact.Email == SecondContact.Email)
                {
                    System.Debug('Both Emails match - ' + FirstContact.Email);
                    
                    if(
                        (FirstContact.EMail_Preferences_Last_Modified_Date__c != NULL && SecondContact.EMail_Preferences_Last_Modified_Date__c != NULL && FirstContact.EMail_Preferences_Last_Modified_Date__c >= SecondContact.EMail_Preferences_Last_Modified_Date__c)
                        ||
                        ((FirstContact.EMail_Preferences_Last_Modified_Date__c == NULL || SecondContact.EMail_Preferences_Last_Modified_Date__c == NULL) && FirstContact.LastModifiedDate >= SecondContact.LastModifiedDate)
                        )
                    {
                        System.Debug('FirstContact Preferences win');
                        
                        //Copy SecondContact details to temp variables to be copied over to master record
                        Temp_EXTERNALID = SecondContact.EXTERNAL_ID__c;
                        Temp_EmailSubscriptions = SecondContact.Email_Subscriptions__c;
                        Temp_ContactSource = SecondContact.Contact_Source__c;
                        
                        // Merge the record
                        System.Debug('Starting Merge');
                        System.Debug('First Contact Id - ' + FirstContact.Id);
                        System.Debug('Second Contact Id - ' + SecondContact.Id);
                        
                        merge FirstContact SecondContact;    // FAILS HERE :(
                        System.Debug('Merge Complete');
                        
                        //Copy the merged record details to surviving record
                        if(FirstContact.EXTERNAL_ID__c == NULL && Temp_EXTERNALID != NULL)
                        {
                            FirstContact.EXTERNAL_ID__c = Temp_EXTERNALID;
                        }
                        
                        FirstContact.Email_Subscriptions__c = Temp_EmailSubscriptions;
                        FirstContact.Contact_Source__c = Temp_ContactSource;    
                        
                        //Since SecondRecord is merged, we don't want to work on it now, so pass it ... increment the counter
                        cnt++;
                        System.Debug('Counter now changed to - ' + cnt);
                        
                    }
                    else if(
                        (FirstContact.EMail_Preferences_Last_Modified_Date__c != NULL && SecondContact.EMail_Preferences_Last_Modified_Date__c != NULL && FirstContact.EMail_Preferences_Last_Modified_Date__c < SecondContact.EMail_Preferences_Last_Modified_Date__c)
                        ||
                        ((FirstContact.EMail_Preferences_Last_Modified_Date__c == NULL || SecondContact.EMail_Preferences_Last_Modified_Date__c == NULL) && FirstContact.LastModifiedDate < SecondContact.LastModifiedDate)
                        )
                    {
                        System.Debug('SecondContact Preferences win');
                        
                        Temp_EXTERNALID = FirstContact.EXTERNAL_ID__c;
                        Temp_EmailSubscriptions = FirstContact.Email_Subscriptions__c;
                        Temp_ContactSource = FirstContact.Contact_Source__c;
                        
                        merge SecondContact FirstContact;
                        if(SecondContact.EXTERNAL_ID__c == NULL && Temp_EXTERNALID != NULL)
                        {
                            SecondContact.EXTERNAL_ID__c = Temp_EXTERNALID;
                        }
                        SecondContact.Email_Subscriptions__c = Temp_EmailSubscriptions;
                        SecondContact.Contact_Source__c = Temp_ContactSource;
                        
                    }
                    
                }    //If Email matches closing
            
            
        } // For Loop
        
        System.Debug('Out of For loop - Lets see if the updating the list works with merged records');
        update lstContacts;
            
    }
    
}
Bhanu MaheshBhanu Mahesh

Hi Sunil,

This is because you list contains LastModifiedDate field which is a Read-Only field.

You have to remove that field before updating the record.

As merge will update the contacts, this field is giving the exception

But as per your code LastModified is require for you to get the winning preference
You can try by cloning the reference of contact before merging it

Instead of this line
merge FirstContact SecondContact;

Try this by cloning FirstContact and SecondContact without timeStamps

Contact firstCon = FirstContact.clone(true);
Contact secondCon = SecondContact.clone(true);
merge firstCon  secondCon ;

Same goes with this statement also merge FirstContact SecondContact; 
Clone it before merging

NOTE: Apply this as per user requirement. This is just an idea

Regards,
Bhanu Mahesh