I'm implementing Database.Merge to merge duplicate Account records in bulk, but it allows only 3 records to merge. If I perform this dml in loop I'll get Too many DML statements: 151 error, so I have created batch apex and limiting the data, I'm wondering is this the best way to do this
global class DuplicateMergeBatch implements Database.Batchable<sObject>, Database.Stateful {
public String queryString;
global Database.QueryLocator start(Database.BatchableContext BC) {
String ph = '814606';
queryString = 'SELECT Id, Name, Phone, Type FROM Account WHERE Phone =:ph ORDER BY CreatedDate ASC';
return Database.getQueryLocator(queryString);
}
global void execute(Database.BatchableContext BC, List<Account> scope) {
Map<String,List<Account>> accountMap = new Map<String,List<Account>>();
Set<String> accountName = new Set<String>();
Set<String> accountPhone = new Set<String>();
Set<String> accountType = new Set<String>();
for(Account a :scope){
accountName.add(a.Name.toLowerCase());
accountPhone.add(a.Phone.toLowerCase());
accountType.add(a.Type.toLowerCase());
}
//Get All non formula fields of account
String sobjectApiName = 'Account';
Map<String, Schema.SObjectType> schemaMap = Schema.getGlobalDescribe();
Map<String, Schema.SObjectField> fieldMap = schemaMap.get(SobjectApiName).getDescribe().fields.getMap();
List<String> fieleList = new List<String>();
for(String fieldName : fieldMap.keySet()){
Schema.DescribeFieldResult fieldResult = fieldMap.get(fieldName).getDescribe();
if(!fieldResult.isCalculated() && fieldResult.isCreateable() && !fieldResult.isExternalId()){
fieleList.add(fieldName);
}
/*if(fieldName != 'isPartner' && fieldName != 'IsCustomerPortal'){
fieleList.add(fieldName);
}*/
}
String fetchFields = 'SELECT '+String.join(fieleList,',')+' FROM '+sobjectApiName+' WHERE Name IN :accountName AND Phone IN :accountPhone AND Type IN :accountType ORDER BY CreatedDate ASC limit 5';
integer i = 1;
for(Account a : Database.query(fetchFields)){
String key = a.Name+a.Phone+a.Type;
key = key.toLowerCase();
if(accountMap.containsKey(key)){
accountMap.get(key).add(a);
}else {
accountMap.put(key,new List<Account>{a});
}
i++;
}
System.debug('i >'+i);
System.debug('accountMap >> '+accountMap);
List<Account> mergeList;
for(String key : accountMap.keySet()){
System.debug('Size >>'+ accountMap.get(key).size());
if(accountMap.get(key).size()>1 && accountMap.get(key).size() <6){
mergeList = new List<Account>();
Account masterAccount = accountMap.get(key)[0];
mergeList.addAll(accountMap.get(key));
mergeList.remove(0);
System.debug('mergeList >> '+mergeList);
for(Account a : mergeList){
Database.MergeResult mergeResult = Database.merge(masterAccount, a, true);
}
}
}
//if(mergeList.size()>0)
// update mergeList;
}
global void finish(Database.BatchableContext BC) {
}}
to execute this batch :
Database.executeBatch(new DuplicateMergeBatch(), 5);