1

This question may asked in many posts and blogs but this became nightmare for me now. Please help me to overcome this issue Issue is

Apex Heap Size Limit Exception while Saving a Record

We have trigger in Asset Object to fire whenever it is updated. Apex class is called inside the trigger. So the logic is below

public override void beforeUpdate() {
    setUpdatedAssetLastValidatedFields();
}

public static void setUpdatedAssetLastValidatedFields() {
    Transient String logicHistory;

    for (Asset assetProcess : (List<Asset>) Trigger.new) {

        Asset oldAsset = (Asset) Trigger.oldMap.get(assetProcess.id);
            logicHistory = assetProcess.assetLastValidatedLogicHistory__c +
                    'Timestamp                                     = ' + System.now() + '\n' +
                    'User ID                                       = ' + UserInfo.getUserId() + '\n' +
                    'User Name                                     = ' + UserInfo.getUserName() + '\n' +
                    'INPUTS:\n' +
                    'old Install_Street1__c                        = ' + oldAsset.Install_Street1__c + '\n' +
                    'old Install_Street2__c                        = ' + oldAsset.Install_Street2__c + '\n' +
                    'old Install_City__c                           = ' + oldAsset.Install_City__c + '\n' +
                    'old Install_State_Province__c                 = ' + oldAsset.Install_State_Province__c + '\n' +
                    'old Install_Zip_Code__c                       = ' + oldAsset.Install_Zip_Code__c + '\n' +
                    'old Install_Country__c                        = ' + oldAsset.Install_Country__c + '\n' +
                    'new Install_Street1__c                        = ' + assetProcess.Install_Street1__c + '\n' +
                    'new Install_Street2__c                        = ' + assetProcess.Install_Street2__c + '\n' +
                    'new Install_City__c                           = ' + assetProcess.Install_City__c + '\n' +
                    'new Install_State_Province__c                 = ' + assetProcess.Install_State_Province__c + '\n' +
                    'new Install_Zip_Code__c                       = ' + assetProcess.Install_Zip_Code__c + '\n' +
                    'new Install_Country__c                        = ' + assetProcess.Install_Country__c + '\n' +
                    'LOGIC DECISIONS:\n';

        assetProcess.assetLastValidatedLogicHistory__c = logicHistory.right(131072);
}

So the problem is, when I have above 50 records to update, then the string 'logicHistory' is keep building the heap size. So is there any workaround to overcome this?.

I am already using Transient keyword in the string variable but it is not reducing the size.

7
  • 1
    try to directly assign the value to this field assetProcess.assetLastValidatedLogicHistory__c second option is declare the string inside for loop. Oct 24, 2016 at 9:30
  • @TusharSharma - I tried these both the ways but problem continues. I tried declaring the variable inside loop and as well as direct assignment.
    – Prince
    Oct 24, 2016 at 9:38
  • How long is that string in average/max case? Is that only logic in trigger?
    – kurunve
    Oct 24, 2016 at 9:43
  • @kurunve - There are logics inside the trigger. This is one of the before update method in the trigger. Before this method current heap size is just 1090 but after this method it is reaching 10345982. Which is exceeding the 6MB of heap size
    – Prince
    Oct 24, 2016 at 9:49
  • @Prince sorry, missed that part where you're always appending log string into previous value. in that case, answer below is only possible one I think. Probably, you can make few queueable jobs with few records in each and string which needs to be appended as parameter to that job. That can save you some heap size.
    – kurunve
    Oct 24, 2016 at 9:54

1 Answer 1

1

You can change the approach for creating logs.

Instead of actions performed in setUpdatedAssetLastValidatedFields you can put the pair (via DML): assetProcess, oldProcess along with userId, timestamp to new object AssetLastValidatedLogicHistory__c and build the result string afterwards (separately for each record or chunk of records via async/batch process).

2
  • By your answer, I can understand that you are saying to move the things to Batch Class instead of normal class. No other possible ways?.
    – Prince
    Oct 24, 2016 at 9:03
  • Batch or queueable apex... you just cannot process this amount of data in single transaction. The great solution could be formula field (to build the log string) but they also have limits (length).
    – Marcin Sz.
    Oct 24, 2016 at 9:33

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .