Salesforce URLFOR redirecting to a Visualforce page which is part of a package

This is a quick one but we struggled a little bit before finding out how to make it work.

Requirement: Redirect to a Visualforce page which is part of a package from a Javascript button.

URLFOR($Page.NAMESPACE__MYPAGE) doesn’t even compile…

but the following works like a charm !

URLFOR(“/apex/NAMESPACE__MYPAGE”);

yes it’s 2 _ in between

Posted in Development, Uncategorized, Visualforce | Tagged , , , , | 1 Comment

Salesforce generates “Unknown Exception” during Deployment

Have you ever encountered an “Unknown exception” error message when trying to deploy/validate a Deployment Set ? Something like the following ?

Image

It doesn’t really provide you with a lot of information, so no idea what to do right ?Before contacting Salesforce Support, maybe it worths giving a try to the following:

Go to the Developer Console and Clear the Heap Dumps !

Image

Hope it helps…

P.S. The explanation behind this, is that the Heap Dumps are also generated during deployment and this requires too much memory ;-)

Posted in Deployment, Development, Exceptions | Tagged , , , , | Leave a comment

Using field sets for dynamic validations in Apex

In Salesforce validations are usually done using the standard functionality offered out of the box.
However there are cases when you need to check specific values but when you perform a certain action i.e. click on a button. In our use case we have to verify that a number of fields are NOT empty before proceeding to the next step.

A typical design for a button is a Visualforce Page and a Controller. In this case you would do the validation in the controller code, probably with an IF statement. It works but not very flexible right ?

Well lets try with field sets ! The idea is to define all fields you need to check in a field set and in the code loop and verify they do have a value. Simply, easy to program and very dynamic ! Do you need more fields to be checked ? Add them in the field set…

And the code to do this is just a couple of lines:

List<Schema.FieldSetMember> lMandatoryfields =
Schema.SObjectType.OBJECT.fieldSets.getMap().get(Label.Req_Fields_Field_Set_Name).getFields();
for (FieldSetMember fSetMember:lMandatoryfields)
{
    if (relatedObject.get(fSetMember.getFieldPath()) == null)
    {
        isError=true;
        sMissingFieldNames.add(fSetMember.getLabel());
    }
}
if (isError)
{
    Apexpages.Message m = new Apexpages.Message(Apexpages.Severity.ERROR, 
                                                Label.Req_Field_Missing_Error_Message);
    Apexpages.addMessage(m);
    for (String strMissingFieldName:sMissingFieldNames)
    {
        Apexpages.Message m1 = new Apexpages.Message(Apexpages.Severity.ERROR,
                                                     strMissingFieldName);
        Apexpages.addMessage(m1);
    }
    return;
}

If you want to do a more complex check you can consider using custom settings.

Posted in apex, Uncategorized | Leave a comment

To SeeAllData or Not to SeeAllData

Recently I came up with a situation where there was a conflict between 2 deployment sets:

The Test Classes in the first deployment set were not using SeeAllData and were inserting all Custom Setting records it required for the Test Classes.

The Test Classes in the second were not using either SeeAllData and were also inserting Custom Setting records.

Where’s the problem ? Both sets were ok independently. BUT the second deployment set was introducing a trigger utilizing Custom Settings which was triggered in the first deployment set ;-) .

So during the deployment of the 2nd the Tests of the first were failing because the trigger could not find the Custom Settings…

Small detail: each deployment set was created from different parties, working in a different sandbox.

Sounds like a mess right ?

My quick fix was to USE SeeAllData in the first deployment set and update the code to use upsert with the Custom Settings Name !

So what is your opinion ?

SeeAllData or NOT ?

Posted in apex, Development | 2 Comments

Use static vs instance methods for Trigger invocations

I had a discussion recently with one of our implementation partners regarding Class methods invoked from the Apex Triggers.

To be more precise we were (and still are) trying to decide whether using Static methods is preferable than using instance methods in the trigger context.

For example Consider the following Class and suppose we need to call the loop from a Trigger.


which approach is the optimal ?

1)

 if (Trigger.isUpdate && Trigger.isAfter){
     TestClass1 tc = new TestClass1();
     tc.doLoop(lA);
 }

or

2)

if (Trigger.isUpdate && Trigger.isAfter)
{
    TestClass1.doStaticLoop(lA);
}

I believe the 2nd one is better because:

  • Less number of code lines. It doesn’t sound like a big issue, but yet if you consider that triggers usually fire more than once in the same context and multiply by the number of triggers invoked in different objects, this adds unnecessary overhead.
  • Utilizes less memory. The main reason for this is that in the first case you need to construct a new instance each time the trigger is invoked while in the second case you don’t.

So I have performed a quick Test invoking the “Trigger code” twice in the same context, using the Developer Console and the cool features it provides !

And here are my findings.

Case 1)

Case 2)

As you can see in the 2nd Case the Heap size is smaller, but not much smaller… Apparently it’s because of the constructor being called twice, but even without the constructor, the Heap size is smaller in the 2nd case.
And the big question is:

Is there any good reason why to prefer Static vs Instance methods for the Trigger context ?

Thanks for your input !

Posted in Uncategorized | Leave a comment

Update Force.com IDE to v25.0 ?

WARNING: Don’t do it from Eclipse

I tried to update the plugin from the Software and Workspace Center, and then…
“Eclipse executable unable to locate companion library” !

Ooops now what ?

  • don’t waste your time trying to resolve this
  • uninstall and re-install from here. If you use the same workspace as before you will only loose Project credentials which is not nice, but yet, not a big issue.

Hope I saved you from some trouble, but I guess if you clicked on a search engine result to get here….

Posted in Development | Tagged , , | Leave a comment

Deleting Multiple Objects with 1 Batch Job

Ever had the requirement to delete objects with a Batch job ? This is very common when you have external interfaces in your org. Usually you need to delete multiple objects, so do you setup multiple batch jobs ?

How about doing this with just one batch job ?

See below code and let me know if you have questions…

global class ManosTestBatchMultiple implements Database.batchable{

    global Iterable start(Database.batchableContext info){
        return new ManosTest();
    }

    global void execute(Database.batchableContext info, List scope){
        List lToDelete=new List();
        for(SObject s : scope){
            lToDelete.add(s);
        }
        delete lToDelete;
    }
    global void finish(Database.batchableContext info){}

    global class ManosTest implements Iterable {
        global Iterator Iterator(){
            return new ManosTestIterable();
        }
    }
}

but the interesting part is in the following piece of code.
WARNING: This is NOT an OPTIMAL coding solution, its just give you an idea how to do it

global class ManosTestIterable implements Iterator{
    List<List> lToDelete {get; set;}
    Integer i {get; set;}
    Integer size {get; set;}
    Integer size1 {get; set;}

    public ManosTestIterable(){
        List lToDelete1 = [SELECT Id
                             FROM TestManos__c
                            WHERE Deletion_Flag__c = true];

        List lToDelete2 = [SELECT Id
                            FROM TestManos2__c
                           WHERE Deletion_Flag__c=true];

        size = 0 ;

        lToDelete = new List<List>();
        lToDelete.add(lToDelete1);
        size += lToDelete1.size();
        size1 = lToDelete1.size();
        lToDelete.add(lToDelete2);
        if (lToDelete2 != null)
            size += lToDelete2.size();
        i = 0;
    }

    global boolean hasNext(){
        if (i >= (size-1)){
            return false;
        } else {
            return true;
       }
    }

    global SObject next()
    {
        if(i == (size-1))
        {
            return null;
        }
        i++;
        if (i <=size1)
        {
            return lToDelete[0][i-1];
        }
        else
        {
            return lToDelete[1][i-size1-1];
        }
    }
}

Posted in Uncategorized | Tagged , , | Leave a comment