You need to sign in to do that
Don't have an account?

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;
}
}
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;
}
}
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