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
Muhammad SahilMuhammad Sahil 

List has more than 1 row for assignment to SObject on line: 35

i want to upload a csv using vf page that would contain parent accounts with corresponding child accounts, and i want to merge them using batch instead of doing this manually but i am getting error " List has more than 1 row for assignment to SObject on line: 35" on my batch, 
my vf page is 
<apex:page controller="MergeChildAccountsController">
    <apex:form enctype="multipart/form-data">
        <apex:inputFile value="{!csvFile}" />
        <apex:commandButton action="{!processCsv}" value="Process CSV" />
    </apex:form>
</apex:page>
============================================
my controler is 
public class MergeChildAccountsController {
    public Blob csvFile { get; set; }
    
    public void processCsv() {
        String[] filelines = csvFile.toString().split('\n');
        List<Account> childAccounts = new List<Account>();
        Map<String, String> parentMap = new Map<String, String>();
        
        for (Integer i = 1; i < filelines.size(); i++) {
            String[] fields = filelines[i].split(',');
            String accountName = fields[0].trim();
            String parentName = fields[1].trim();
            
            Account child = new Account(Name = accountName);
            childAccounts.add(child);
            parentMap.put(accountName, parentName);
        }
        
        Database.executeBatch(new MergeChildAccountsBatch(childAccounts, parentMap));
    }
}
====================================

my batch is 
public class MergeChildAccountsBatch implements Database.Batchable<Account> {
    List<Account> childAccounts;
    Map<String, String> parentMap;
    
    public MergeChildAccountsBatch(List<Account> childAccounts, Map<String, String> parentMap) {
        this.childAccounts = childAccounts;
        this.parentMap = parentMap;
    }
    
    public Iterable<Account> start(Database.BatchableContext bc) {
        return [SELECT Id, Name, ParentId FROM Account WHERE Name IN :parentMap.keySet() OR Id IN :childAccounts];
    }
    
    public void execute(Database.BatchableContext bc, List<Account> parentAccounts) {
        try {
            Map<String, Account> nameToAccountMap = new Map<String, Account>();
            
            for (Account account : parentAccounts) {
                nameToAccountMap.put(account.Name, account);
            }
            
            Set<Account> accountsToMerge = new Set<Account>();
            for (Account child : childAccounts) {
                String parentName = parentMap.get(child.Name);
                if (parentName != null) {
                    List<Account> parentList = [SELECT Id, Name, ParentId FROM Account WHERE Name = :parentName];
                    accountsToMerge.addAll(parentList);
                }
            }
            
            Database.MergeResult[] mergeResults = Database.merge(nameToAccountMap.values(), new List<Account>(accountsToMerge), false);
           system.debug('mergeResults' +mergeResults);
            
            
           /* for (Database.MergeResult result : mergeResults) {
                if (result.isSuccess()) {
                    // do something with the merged account
                } else {
                    // handle the merge failure
                }
            } */
        } catch (Exception e) {
            System.debug('Error: ' + e.getMessage() + ' on line: ' + e.getLineNumber());
        }
    }
    
    public void finish(Database.BatchableContext bc) {
        // do nothing
    }
}
Shivdeep KumarShivdeep Kumar
Hi Sahil,

you are getting the error because of account query based on Name.
List<Account> parentList = [SELECT Id, Name, ParentId FROM Account WHERE Name = :parentName];
Account could have multiple records with same Name. It's better to use the Id OR some unique field value. If you want to use your query, you have to use the LIMIT like- List<Account> parentList = [SELECT Id, Name, ParentId FROM Account WHERE Name = :parentName LIMIT 1];

Please let me know if this help!

Thanks,
Shivdeep kumar
Muhammad SahilMuhammad Sahil
hi Shivdeep, heres the updated controler and batch but the error still exists:
public class MergeChildAccountsBatch implements Database.Batchable<Account> {
    List<Account> childAccounts;
    Map<Id, Id> parentMap;
    
    public MergeChildAccountsBatch(List<Account> childAccounts, Map<Id, Id> parentMap) {
        this.childAccounts = childAccounts;
        this.parentMap = parentMap;
    }
    
    public Iterable<Account> start(Database.BatchableContext bc) {
        return [SELECT Id, Name, ParentId FROM Account WHERE Id IN :parentMap.values() OR Id IN :childAccounts];
    }
    
    public void execute(Database.BatchableContext bc, List<Account> parentAccounts) {
        try {
            Map<Id, Account> idToAccountMap = new Map<Id, Account>();
            
            for (Account account : parentAccounts) {
                idToAccountMap.put(account.Id, account);
            }
            
            Set<Account> accountsToMerge = new Set<Account>();
            for (Account child : childAccounts) {
                Id parentId = parentMap.get(child.Id);
                if (parentId != null) {
                    List<Account> parentList = [SELECT Id, Name, ParentId FROM Account WHERE Id = :parentId];
                    accountsToMerge.addAll(parentList);
                }
            }
            
            Database.MergeResult[] mergeResults = Database.merge(idToAccountMap.values(), new List<Account>(accountsToMerge), false);
            System.debug('mergeResults: ' + mergeResults);
        } catch (Exception e) {
            System.debug('Error: ' + e.getMessage() + ' on line: ' + e.getLineNumber());
        }
    }
    
    public void finish(Database.BatchableContext bc) {
        // do nothing
    }
}
=============
public class MergeChildAccountsController {
    public Blob csvFile { get; set; }
    
    public void processCsv() {
        String[] filelines = csvFile.toString().split('\n');
        List<Account> childAccounts = new List<Account>();
        Map<Id, Id> parentMap = new Map<Id, Id>();
        
        for (Integer i = 1; i < filelines.size(); i++) {
            String[] fields = filelines[i].split(',');
            String accountId = fields[0].trim();
            String parentId = fields[1].trim();
            
            Account child = new Account(Id = accountId);
            childAccounts.add(child);
            parentMap.put(accountId, parentId);
        }
        
        Database.executeBatch(new MergeChildAccountsBatch(childAccounts, parentMap));
    }
}
 
Laquita ScholzLaquita Scholz
I totally like your gave limits as the post you passed on has some uncommon information which is totally essential for me. MyFamilyMobile (https://www.myfamilymobile.net/)
Shivdeep KumarShivdeep Kumar
Hi Sahil,

Did you try to save your code and try to run?
As I can see in your code that this code can't be saved. 
you are using the set of Account, which can't be possible. Please try to save the code from your end after that let me know what new.

Thanks,