You need to sign in to do that
Don't have an account?

Trigger being called twice
Hello,
I have a trigger on Account and it is being called twice I am do not know how to figure this out.
Here is my trigger code
trigger AccUpdateRates on Account (before insert, before update) { for(Account a: Trigger. new){ if(Trigger.isUpdate){ Account beforeUpdate = System.Trigger.oldMap.get(a.Id); if(a.RecordTypeId == '012500000001LcY' && a.Termination_Date__c == null){ } } if(Trigger.isInsert){ if(a.RecordTypeId == '012500000001LcY' && a.product__c != null){ AccList.add(a); prodIDs.add(a.product__c); } } if(accList.size()>0) AccountUpdateRates.UpdateProductRates(AccList, ProdIDs); } }
I see that I have Kugadd package installed and have similar trigger on account.
Trigger - AccountBeforeInsertBeforeUpdate - installed package Kugamon Account/Contact Sync
I put print statement in couple of place in my class that is being called from trigger.
When I look at the debug log I see the following statement twice
16:05:48.163|CODE_UNIT_STARTED|[EXTERNAL]|01qP00000004GdG|AccUpdateRates on Account trigger event BeforeUpdate for [0015000000XLDub]
Any suggestions I can find what is my causing trigger to be called twice?
Thanks
Uma
http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_triggers_order_of_execution.htm
According to this your trigger is hitting a workflow that changes the record again and then it redoes the trigger.
Thanks for the information. how can I prevent from trigger being called twice?
what should I look for in debug log?
Is there any check I can do to make sure that the trigger does not fire second time?
There is no any straight way to prevent execution of trigger,
here is workaround.
Create a Boolean Field on your Object, like flag__c
Now update this flag while updating records ..via apex or Workflow rule field upadate
Use this same field as controlling field in Apex code
In this way , You can avoid execution of Core logic of Trigger
Hope This will help you,
Thanks,
Bala
Just to add to Bala's response, this boolean flag should be static, so that it is available throughout the execution context.
http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_classes_static.htm
I don't think you should focus on finding a way to stop your trigger from being called multiple times in one execution 'stream'. Rather, I think you'd be better served by making sure that your trigger only does necessary work each time it's called. Right now perhaps you only have that one package you've mentioned, but later you may have more, and other packages can also install workflows and triggers that in turn may call yours again and again, etc.
For example, the first time your trigger executes I assume you plan to call UpdateProductRates. But, the second time through your trigger I'd guess that there would be something set by the UpdateProductRates call that you could check to see if an update is required. If it is, do it, otherwise don't.
Some other thoughts:
1. Don't hardcode your RecordtypeId's. use:
if (a.RecordTypeId == [select id from RecordTypes where sobjecttype= 'Account' and Name='theRecordTypeName'].id;
If you use that ID several times, create a local ID variable and retrieve it once.
2. Push logic into your utility libraries. For example, in this usage, the UpdateProductRates utility is taking parallel lists of Account SObjects and Product ID's. However, all the Product ID information is already in the Account information. So, why not write an UpdateProductRates(List<Account> accs) version that accepts the list and (if needed) extracts the product ID's into it's own list. Take that logic out of the trigger.
Also, going back to the first paragraph, call UpdateProductRates multiple times... let *that* library figure out if there's work to do on it's targets. (And it should check for isEmpty() on it's arguments as well and return right away if the argument list(s) is empty.)
Hope this helps, Best, Steve.
Thanks for all the suggestions.
I took all the points mentioned by SteveBower into consideration and made changes to my trigger and class.
I am creating a task in my package that acts as a Activity History. This task is being created twice. Insert Task in apex Class because the tirgger is being called twice. I am trying to prevent that.
Secondly, I am setting a flag Updated ="True" to prevent users from making changes again within one hour
I tried last modified Date compare with date.Today() that did not work. Because Last Modified date is localized where are date.Today() is server time
Instead of Date.today(), could you compare it with DateTime.now()? LastModifiedDate is stored as Coordinated Universal Time.
It's converted by the UI to your timezone, however programatically LastModifiedDate should be directly comparable to DateTime.now(). You should be able to do the comparison in the Query so you don't even have to retrieve the values and check them, you should just be able to do a count() and see if you get any records back.
Best, Steve.
p.s. I won't ask why you're not using the build-in Activity History capabilities, but be sure to consider it.
Hi,
As a response to your question on using static variables: I try to keep away from it, as it will not always work correctly when working with sets of records larger than 100. In that case, the data is processed in subsets of 200 (each in a separate context) and then within the trigger the subset of 200 is processed in 2 separate sets of 100.
The Static Boolean will be set after the first 100 records have been processed, causing the trigger NOT to run for the second set of 100.
We had many problems in our org because of this strange APEX behaviour.... I'm puzzled by why this subdivision is made and why it was not simply made 1 dataset in 1 context...
Hope that helps,
Guy
Hi Guy,
Were you able to resolve this issue with static variable that prevents the trigger to be executed?
Thanks,
Cathy
Yes, I am able prevent calling trigger twice by using static variable
In the controller
and here is the static variable value reset
1 small remark on my point above: it seems that this only happens when working with the WebService API and not when e.g. updating 200 records via the List View inline edit function.
It appears to me that the only 100% secure option is to work with a checkbox field on the record, that indicates whether or not the trigger as run. Then an @future that resets the checkbox back to unchecked.
This was also recommended to me by salesforce developer support.
Rgrds,
Guy
Hi Guy,
Thanks for sharing. I'm actually encountering this issue in Batch APEX. May I know how you implemented the @future?
Thanks,
Cathy
Here's the class with the static share property:
Then added to the trigger: