1

I have created the following trigger with the main purpose of camel case some fields in the account object. However it seems to be breaking when I do bulk uploads (uploading business and person accounts, if it is only 1 type it doesnt break).

The fields I am looking to camel case are:

For business account: the name.

For Person Accounts: First, middle and last name

and for both the address: BillingStreet, BillingCity, BillingState, BillingCountry

I thought that this code was already bulkify

Trigger:

trigger Account_BIBU on Account (before insert, before update) {
    Account_HDL_BIBU hdl = new Account_HDL_BIBU();

    //handleBeforeUpdate and handleBeforeInsert: update the account with camel case
    if(Trigger.isInsert && Trigger.isBefore) {
        hdl.handleBeforeInsert(Trigger.new, Trigger.old);
    } else if(Trigger.isUpdate && Trigger.isBefore) {
        hdl.handleBeforeUpdate(Trigger.new, Trigger.old, Trigger.oldMap);
    }
}

Class: (Edit I have updated the class)

Error Sample:

Update failed. First exception on row 2 with id 00628000002tD2FAAU; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, Account_BIBU: execution of BeforeUpdate

caused by: System.SObjectException: Invalid field Name for Account

public with sharing class Account_HDL_BIBU {
    public void handleBeforeInsert(List<Account> newRec,List<Account> oldRec){
        updateRecords(newRec, oldRec, null); 
    }

    public void handleBeforeUpdate(List<Account> newRec,List<Account> oldRec, Map<ID, Account> oldMap){
        updateRecords(newRec, oldRec, oldMap);
    }   

    private void updateRecords(List<Account> newRec,List<Account> oldRec, Map<ID, Account> oldMap) {
        for(Account a:newRec){
            camelCase(a);
        }   
    }

    public void camelCase(Account a){
        List<String> fields = new List<String>();
        if(a.IsPersonAccount == false){
            fields = new List<String> { 'BillingStreet', 'BillingCity', 'BillingState', 'BillingCountry', 'Name' };
        }else{
            fields = new List<String> { 'BillingStreet', 'BillingCity', 'BillingState', 'BillingCountry', 'FirstName', 'MiddleName', 'LastName'};
        }
        String newName;
        String fnValue = '';
        List<String> nameLST = new List<String>();
        Object fieldValue;
        for(String fieldName:fields){
            if(a.get(fieldName) != null){
                fieldValue = a.get(fieldName) ;
                fnValue = String.valueOf(fieldValue);
                if(fnValue != null){
                    newName = '';
                    fnValue = fnValue.toLowerCase();
                    nameLST = fnValue.split(' ');
                    for(String s: nameLST){
                        newName = newName + s.substring(0,1).toUpperCase()+s.substring(1,s.length()) + ' ';
                    }
                    a.put(fieldname,newName);
                }
            }
        }
    }
}

Query result as true but trigger result seems to be false?

EDIT

It seems, it is a know issue in Salesforce, however the workaround its not working for me.

Issue Link: https://success.salesforce.com/issues_view?id=a1p30000000T24QAAS

8
  • Can you be more specific about what you mean by "sometimes it breaks"? Perhaps the problem is not bulkification related but is data related.
    – Keith C
    Mar 22 '16 at 8:26
  • When u do a mass upload if u select update record in batches of 1, the code works fine, but if u select a greater number sometimes it breaks, i think it is when in the batch are mixed record types, i could be wrong, however the code sometimes don't work as i specify there
    – manza
    Mar 22 '16 at 8:30
  • 1
    Someone else may but I don't see a bulkification problem. I suggest you write some unit tests to try to find out what breaks. (And as an aside you don't have to return the Account from each method as Apex works by reference i.e. you can modify the Account that is passed into the methods.)
    – Keith C
    Mar 22 '16 at 8:47
  • Thank you Keith, regarding your side note, you mean instead of having public account camelCase(Account a, String fieldName) change that to public void camelCase(Account a, String fieldName)? sorry to ask what will the main advantage on doing it this way?
    – manza
    Mar 23 '16 at 0:50
  • i'm not sure this code handles 0 length strings in fnValue properly
    – cropredy
    Mar 23 '16 at 2:04
0

As my comment/edit, is a known issue with salesforce when using both person and business account and trying to retrieve the Name of a business account, this was my work around, I hope if someone is trying to do something similar it helps:

public with sharing class Account_HDL_BIBU {
    public void handleBeforeInsert(List<Account> newRec,List<Account> oldRec){
        updateRecords(newRec, oldRec, null); 
    }

    public void handleBeforeUpdate(List<Account> newRec,List<Account> oldRec, Map<ID, Account> oldMap){
        updateRecords(newRec, oldRec, oldMap);
    }   

    private void updateRecords(List<Account> newRec,List<Account> oldRec, Map<ID, Account> oldMap) {
        List<String> fields = new List<String>();
        for(Account a:newRec){
            if(a.IsPersonAccount == false){
                fields = new List<String> { 'BillingStreet', 'BillingCity', 'BillingState', 'BillingCountry' };
                a.Name = theWord(a.Name);
            }else{
                fields = new List<String> { 'BillingStreet', 'BillingCity', 'BillingState', 'BillingCountry', 'FirstName', 'MiddleName', 'LastName'};
            }
            camelCase(a,fields);
        }   
    }

    public void camelCase(Account a, List<String> fields){
        String newWord = '';
        for(String fieldName:fields){
            if(a.get(fieldName) != null){
                if(String.valueOf(a.get(fieldName)) != null){
                    newWord = theWord(String.valueOf(a.get(fieldName)));
                    a.put(fieldname,newWord);
                }
            }
        }
    }

    public String theWord(String fnValue){
        String newName = '';
        fnValue = fnValue.toLowerCase();
        List<String> nameLST = new List<String>();
        nameLST = fnValue.split(' ');
        for(String s: nameLST){
            newName = newName + s.substring(0,1).toUpperCase()+s.substring(1,s.length()) + ' ';
        }
        return newName;
    }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.