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
bohemianguy100bohemianguy100 

DML insert statement within trigger

I need to create a trigger that will insert new records, but I cannot use a DML insert statement to create new records on the object that is firing the trigger.

 

Is there an alternative?  Some other method to accomplish this?

 

Here is a stripped down prototype of what I'm trying to do:

 

trigger FullfillmentGetAccountHierarchy on Fulfillment__c (before insert) { // Other code occurs here to get the values dynamically for the hard-coded values below List<Fulfillment__c> fuls = new List<Fulfillment__c>(); for (Integer i = 0; i < 6; i++) { Fulfillment__c ful = new Fulfillment__c(); ful.Contact__c = '003S0000006owfN'; ful.Account__c = '001S000000AUd0r'; ful.Fulfillment_Request__c = 'a0AS000000214OJ'; fuls.add(ful); } insert(fuls); }

Is there any way to insert new records using a trigger on the object that fires the trigger?  Any suggestions? 

 

Thanks.

Message Edited by bohemianguy100 on 03-04-2010 08:47 AM
cloudcodercloudcoder
You could use a @future method, but you will need to make sure that you update your original trigger so you don't get into a recursive loop (future method inserts new Fullfillment objects which fires the trigger, which calls the future method and so on)
bohemianguy100bohemianguy100

I tried to create a simple prototype using a @future method.  I didn't get any errors, but the new records are not created?

 

Here is the trigger:

 

trigger FulfillmentAsyncInsert on Fulfillment__c (after insert) { FulfillmentAsyncTrigger.processRelatedAccounts(Trigger.newMap.keySet()); }

Here is the class with the method:

 

 

public class FulfillmentAsyncTrigger { @future public static void processRelatedAccounts(Set<Id> accountIds) { List<Account> accts = [Select Id, ParentId From Account Where Id in: accountIds]; // There is a lot of logic to pull the necessary data going on in this section, which I have // omitted for brevity // Here I'm just trying to prove the concept that the new fulfillment records will get inserted. List<Fulfillment__c> fuls = new List<Fulfillment__c>(); for (Integer i = 0; i < 6; i++) { Fulfillment__c ful = new Fulfillment__c(); ful.Contact__c = '003S0000006owfN'; ful.Account__c = '001S000000AUd0r'; ful.Fulfillment_Request__c = 'a0AS000000214OJ'; fuls.add(ful); } insert fuls; } }

 

 

Am I missing anything?

cloudcodercloudcoder

 The future call looks like (apart from a small nitpick too, but you may want to not use the word trigger in your class (it's not a trigger)) but you are going to have recursion problems. Right now your process is:

 

after insert - call FullfillmentAsyncInsert

call future method - insert more Fullfillment__c objects

after insert - call FullfillmentAsyncInsert

call future method ........ and so on.

 

Also, I am assuming you are not really hardcoding ids in your trigger, and just doing in the post as an example. Hardcoding ids is never a good idea 

 

bohemianguy100bohemianguy100

I will rename the class, I just threw it in the sandbox environment since I'm just trying to prototype the functionality and get a working example.  The same with the hardcoded values.  It just used that as an example, I will be populating the field values dynamically.

 

I understand the recursion problem you've identified.  Is there an example I might be able to take a look at to see how to prevent the recursion?

 

I'm still not clear on why the insert didnt' work using the @future method?  Shouldn't I be getting new records added, even though I have the recursion problem.

cloudcodercloudcoder

Jeff Douglas has a great post on this: http://blog.jeffdouglas.com/2009/10/02/preventing-recursive-future-method-calls-in-salesforce/

 

HTH 

FaridKognozFaridKognoz

One way of not getting into an infinite loop is to have a checkbox on the record that controls the propagation. For example you create a record that fires the trigger if the checkbox is true then you call the @future method. On the @future method you create records with this checkbox on false. So this time when the trigger is fired will not attempt to call the @future metho. In fact, calling a @future method from a @future thread throws an exception so that's one thing you don't want to do.

 

As for the recursion problem and the records not being inserted I guess this is exactly what happened. The @future executes and fires the insert trigger, this trigger tries to make an  @future call and this throws an exception.

 If you take a look at the debug logs I bet you will find the answer.