You need to sign in to do that
Don't have an account?
Muhammad 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
}
}
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
}
}
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
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));
}
}
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,