You need to sign in to do that
Don't have an account?
Creating Records, the Bulk-Safe Way
Hi,
I have been working on "bulkifying" my Apex, and lowering overall SOQL usage. I am running into a slight problem with creating a new record.
Usually, I include the syntax to create a new record within a for loop, under the trigger.new record; however, when running mass updates, I get the 21 SOQL limit error. When I put the new-record syntax outside the for loop, I don't get the error; but, it only creates one record, which is related to the entire batch rather than creating a new entry for every record that passes through the update.
My original code creates a record for each entry being updated, but hits SOQL limits in bulk:
for(Lead l:trigger.new){ Custom_Object__c co = new Custom_Object__c(); insert co; l.Custom_Lookup__c=co.Id; }
My updated code is not getting the SOQL error, but only creates one record for the entire batch (rather than 200 records, one for each):
Custom_Object__c co = new Custom_Object__c(); insert co; for(Lead l:trigger.new){ l.Custom_Lookup__c=co.Id; }
Does anyone have any suggestions or ideas on how I can fix this issue, and still keep my code "bulk-safe". I need to create a record for each entry that passes through the update, without hitting the SOQL limit. Any help you can give me would be highly appreciated.
Thanks!
Instead of inserting your record one at a time, add each record inside your loop to a list and then insert the entire list.
List<Custom_Object__c> myList = new List<Custom_Object__c>();for(Lead l:trigger.new){ Custom_Object__c co = new Custom_Object__c(); // do some stuff before myList.add(co);}insert myList;
HTH
Jeff Douglas
Appirio, Inc.
http://blog.jeffdouglas.com
Thanks for the response. I changed my code, and all the records are getting inserted as expected; however, it is not letting me assign the new record ID to the lead, so the records are not related after triggering.
List<Custom_Object__c> mylist = new List<Custom_Object__c>();
for(Lead l:trigger.new){
Custom_Object__c co = new Custom_Object__c();
mylist.add(co);
l.Custom_Lookup__c=co.Id;
}
insert mylist;
I think this might be a problem because I am basically trying to create a parent record. Even if I open a new for loop after the records are inserted, it wouldn't be able to determine which record goes where, as far as I can think of. To further complicate things, I am trying to do this upon inserting the lead, so the lead doesn't actually have an ID to reference.
If you have any ideas, it would be greatly appreciated; however, I can already see a possible work-around, but it would involve rewriting many, many lines of code elsewhere to account for the change.
Thanks again!
You can use a map to hold a new instance of your custom object, indexed by the lead Id (run the trigger after insert so the Lead will be in the database, and you will have the Id).
You'll need to iterate through again, and build another collection of Leads, because the post-insert ones in Trigger.new are read-only...
something like :
trigger MyLeadTrigger on Lead (after insert) {
Map<Id, MyObject__c> myMap = new Map<Id, MyObject__c>();
Set<Id> updateLeads = new Set<Id>();
for (Lead l : Trigger.new) {
system.debug('lead = ' + l);
updateLeads.add(l.Id);
MyObject__c co = new MyObject__c(Name='Object_'+l.Name);
myMap.put(l.Id, co);
}
insert myMap.values();
Map<Id, Lead> leads = new Map<Id, Lead>([SELECT Id FROM Lead WHERE Id in: updateLeads]);
for (Lead l : Trigger.new) {
Lead updLead = leads.get(l.Id);
updLead.Custom_Object__c = myMap.get(l.Id).Id;
}
update leads.values();
}
HTH, Ian
:)