Im working on inserting multiple campaign records with a self-relationship. I was hoping to do this with one DML statement using the method described here: Link I know in the first paragraph it says two different SObject types but was hoping there is a work around to this. Here is my current code:
/*
*********************************************************
@Method Name : cloneParentChildCampaigns
@description : This method clones parent and related child campaigns for end of year.
@param : None
@return : None
*********************************************************
*/
@TestVisible private void cloneParentChildCampaigns(){
List<Campaign> currentPCList = new List<Campaign>();
List<SObject> clonedPCList = new List<SObject>();
List<Campaign> currentCCList = new List<Campaign>();
List<SObject> clonedCCList = new List<SObject>();
SObject[] insertSObjectList = new List<SObject>();
Map<Id, Campaign> pcReferenceMap = new Map<Id, Campaign>();
Integer sequentialNum = 0;
// Create and run query for parent campaigns of the current year
date begOfYear = date.parse('1'+'/'+'1'+'/'+ today.year());
date endOfYear = date.parse('12'+'/'+'31'+'/'+ today.year());
String pcQuery = 'SELECT Id, Name, isActive, startDate, endDate, actualCost, status FROM Campaign WHERE ParentId = null AND isActive = true AND startDate = :begOfYear AND endDate = :endOfYear ORDER BY ID ASC';
currentPCList = Database.query(pcQuery);
system.debug('currentPCList : ' + currentPCList);
String ccQuery = 'SELECT Id, ParentId, Name, isActive, startDate, endDate, actualCost, status FROM Campaign WHERE ParentId != null AND isActive = true AND startDate = :currentStartDate AND endDate = :currentEndDate ORDER BY ID ASC';
currentCCList = Database.query(ccQuery);
system.debug('currentCCList : ' + currentCCList);
// Loop through all child campaigns
for (Campaign currentCC : currentCCList) {
Campaign clonedCC = currentCC.clone(false,true,true,true);
// Assign correct values to fields including externalid
clonedCC.name = newMonthlyName(currentCC.name);
clonedCC.isActive = false;
clonedCC.startDate = nextStartDate;
clonedCC.endDate = nextEndDate;
clonedCC.actualCost = null;
clonedCC.status = 'Planned';
clonedCC.Parent = null;
// check if the parentid is alread in the map of Parent campaigns created
if (!pcReferenceMap.containsKey(currentCC.ParentId)) {
// If not add to list and create new refrence to a Parent Campaign
sequentialNum++;
Campaign campaignReference = new Campaign(
ExternalId__c = todayDT.format('yyyyMMdd') + String.valueOf(sequentialNum));
clonedCC.Parent = campaignReference;
clonedCCList.add(clonedCC);
pcReferenceMap.put(currentCC.ParentId, campaignReference);
} else {
clonedCC.Parent = pcReferenceMap.get(currentCC.ParentId);
clonedCCList.add(clonedCC);
}
}
for(Campaign currentPC : currentPCList){
Campaign clonedPC = currentPC.clone(false,true,true,true);
clonedPC.name = newYearlyName(currentPC.name);
clonedPC.isActive = false;
clonedPC.startDate = begOfYear.addYears(1);
clonedPC.endDate = endOfYear.addYears(1);
clonedPC.actualCost = null;
clonedPC.status = 'Planned';
clonedPC.ExternalId__c = pcReferenceMap.get(currentPC.id).ExternalId__c;
clonedPCList.add(clonedPC);
}
insertSObjectList.addAll(clonedPCList);
insertSObjectList.addAll(clonedCCList);
// Check and insert cloned parent campaigns
if(Campaign.sObjectType.getDescribe().isCreateable()){
Database.SaveResult[] results = Database.insert(insertSObjectList);
}
}
Here is my current error as well:
System.DmlException: Insert failed. First exception on row 4; first error: INVALID_FIELD, Cannot specify both an external ID reference Parent and a salesforce id, ParentId: []