Hot answers tagged

113

Here is how I debug my issues. In most cases I would only make it to step 2 before I solve my problem. Step 1: Explain it to your Rubber Duck I try explain what my code is doing to my rubber duck. A lot of the time I figure out the problem when I'm explaining the code to someone else. (If exceptions are involved, take a look at your code at the line ...


109

In Summer '14, (version 31.0), there is a new field available on the Organization object. SELECT IsSandbox FROM Organization LIMIT 1 From the release notes under New and Change Objects: The Organization object has the following new read-only fields. InstanceName IsSandbox You can, for example, create a lazy loader that other classes can ...


61

Good question, but there are MANY possible answers, so I will just throw in my 2 cents. The first and easiest way to 'BULKIFY' is to leverage collections in order to save yourself SOQL calls and DML statements. Here's an older, but still great resource by Jeff Douglass on utilizing collections in Salesforce. http://blog.jeffdouglas.com/2011/01/06/fun-...


57

An easy way to do this is as follows: Use an IDE to create a new project and download all classes from production. In the class you want to delete, open the metadata file and change the status of the class to "deleted". Save to the server. Observe the status of the class in the example below: <?xml version="1.0" encoding="UTF-8"?> <...


54

Callouts cannot be made from triggers as that would hold up the database transaction until the callout completed, which can be up to 120 seconds from a limits perspective. This could obviously cause significant contention with other transactions and impact performance. The only way that you can execute a callout from a trigger is to schedule it to run ...


52

in APIv26 there's a new method, Id.getSObjectType() which returns a sObject token you can use to find it's type. Sample code: String objectAPIName = someId.getSObjectType().getDescribe().getName(); This new style uses much less heap space and script statementsCPU time in addition to being much simpler and is highly recommended. Don't do this anymore, but ...


43

The usual order of execution detailed at http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_triggers_order_of_execution.htm still applies with some special considerations The Before triggers and validation rules do not fire unless that checkbox is ticked under Customise > Lead > Settings. Note that for orgs created prior to '08 you'll need ...


43

The answer provided by Paul Sasik above works, but is not a secure way of generating a UUID because of it's use of Math.Random(), which is not a cryptographically secure pseudo-random number generator. One of two things should be done, either use Crypto.getRandomInteger() to generate the random integer or use the code below as a drop in replacement for the ...


40

Here is a static method that accepts a desired string length as an argument. It takes a full string of ASCII numbers and letters and loops through the index of your desired string length, randomly choosing an index in the full character string. public static String generateRandomString(Integer len) { final String chars = '...


35

You've got the general idea from your answer. Dynamic Apex and Dynamic SOQL are the best way to reflect on SObject's and as you've discovered you can determine the type easily. I would ensure however your method takes a list of SObject so it can implement bulkfication. public void createTask(List<SObject> records) You can use the List method ...


33

This is because you are in an after insert/update trigger and the records are read only in that context as they have been written, but not committed, to the database. Unfortunately your trigger is relying on the ids of the records, which means you won't be able to use before insert as the ids won't be populated at that time (as the records haven't been ...


32

For this, you can reference the Trigger.oldMap and Trigger.newMap map collections. So, you can compare old values with new values. For example: for( Id accountId : Trigger.newMap.keySet() ) { if( Trigger.oldMap.get( accountId ).Antecipado__c != Trigger.newMap.get( accountId ).Antecipado__c ) { // do something here because your field has changed }...


28

(1) To determine the number of Future calls run in the past 24 hours, you can use this utility method: public static Integer GetNumFutureCallsInLast24Hours() { return [select count() from AsyncApexJob where CreatedDate >= :Datetime.now().addHours(-24) and JobType = 'Future']; (2) To dynamically run methods in a future ...


28

Apex Trigger Code Testing Writing test code to invoke Apex Trigger logic is a requirement, even if you have other tests that cover other aspects of the code called from it, such as utility or library methods in other Apex classes. As such you must have at least one Apex test perform the require DML operations on the object to invoke the trigger logic, no ...


27

What is a Recursive Trigger? A recursive trigger is one that is called over and over, if not controlled will result in this error... maximum trigger depth exceeded This is a simple way to create this error via a trigger on an object called Test__c... trigger TestTrigger on Test__c (before insert) { insert new Test__c(); } With the above trigger in ...


26

The record is locked because you are catching the record after the insert DML statement has happened. So if you'd like to modify this record (or records), you will need to query anew, modify, then execute another DML statement. Here is an example of how you could modify your trigger to work: trigger SetProductCategory on OpportunityLineItem (after insert) {...


26

Another good way to avoid recursion is highlighted in Chapter 6 of Dan Applemans's excellent book, Advanced Apex Programming. This particular example is around recursion when looking for a specific field change which is very common in many triggers. As mentioned in @BarCotters answer, you generally run your trigger on very specific criteria. A change in a ...


25

It's not perfect but the static method System.URL.getSalesforceBaseUrl() Will allow you to scrape the instance name, will that be sufficient to distinguish between production and sandbox?


25

You can use !system.isBatch() in your trigger to check if it is fired from within a batch or not


25

Contrariwise, I will provide an argument for upgrading, although the other answers state that complacency is acceptable. There are two factors at play when you speak of API versions: features and consistency. Both of these issues introduce two distinct needs, namely stability and flexibility. First, let's address consistency. You should keep all your ...


24

Use the Describe methods. In the example below, replace My_Object__c with the name of the pertinent sObject. Set<String> objectFields = Schema.SObjectType.My_Object__c.fields.getMap().keySet(); if(objectFields.contains(fieldName)) { //do stuff } Note, don't repeatedly call Schema.SObjectType.My_Object__c.fields.getMap() as there are governor ...


24

You can create random strings by stringing together Integer values. Here's how I would perform such a task: public static String randomStringAll(Integer count) { Integer[] chars = new Integer[0], offsets = new Integer[] { 48, 65, 97 }, mods = new Integer[] { 10, 26, 26 }; while(count > chars.size()) { Integer cat = ...


23

Michael Farrington recently posted an Apex method for this on his blog: http://www.michaelforce.org/recipeView?id=a0Ga000000Ekp65EAB This method uses URL.getSalesforceBaseUrl().getHost() which should work in a trigger.


22

After working with the code in techtrekker's link (in OP comments) and other resources I cobbled together a standalone, working class for generating GUIDs in Apex code: Sample usage: if (acct.AccountUuid__c == null) acct.AccountUuid__c = GuidUtil.NewGuid(); Apex class: global class GuidUtil { private static String kHexChars = '...


21

A similar discussion went here and you may find it helpful. What sObject properties don't cause triggers to fire? To answer your question The Trigger will fire.The Document mentions that the Parent record record goes through save procedure meaning the trigger will fire on parent record if there is a modification on the field of child record that feeds ...


21

The answer is, it depends. If you have your code written directly in the trigger or in a class designated without sharing, then the apex code can update records that are locked, regardless of the user who caused the trigger to fire. I tested by creating a trigger on Contact that updates a field on the Contact's Account. When the Account is locked, I can ...


21

You can use the addError method on the SObject for this, the Trigger Exceptions topic of the Apex Developers guide starts to describe the process and links to other topics describing this approach. Marks a record with a custom error message and prevents any DML operation from occurring. Note that you can also apply the addError method call to a field, as ...


21

First, here's a link to Developer Force's Current List of Best Practices for Logic which has links to several articles that apply to bulkifying your code. Here's a link to the Trigger Pattern for Tidy, Streamlined, Bulkified Triggers which is a good place to start if you'd like to implement your triggers as classes and have any and all code for for a ...


21

As per documentation You can't pass sObjects to @future methods: Methods with the future annotation must be static methods, and can only return a void type. The specified parameters must be primitive data types, arrays of primitive data types, or collections of primitive data types. Methods with the future annotation cannot take sObjects or ...


20

It's worth taking a look at Triggers and Order of Execution. It lists out step-by-step what happens when a trigger executes. Specifically, the steps on what happens when workflows fire and the steps on rollup summaries and relations to parents/grandparents is interesting. If the record contains a roll-up summary field or is part of a cross-object ...


Only top voted, non community-wiki answers of a minimum length are eligible