I am trying to convert our existing attachments to contentVersions using batch. But problem I am facing is that some of the attachments are of size greater than 12Mb. So when I try to run my batch I get heap size exceeded exception. Problem is even if a query a attachment body my heap size will exceed the limit. How can I solve this problem. I have some custom logic on attachment records so most of app exchange apps will not work. Can I somehow convert attachments without having to query body from attachment or any other way to not solve this problem.

Attachment attach = [SELECT Id, Name, Body, ContentType, ParentId From Attachment LIMIT 1];

//Insert ContentVersion
ContentVersion cVersion = new ContentVersion();
cVersion.ContentLocation = 'S'; //S-Document is in Salesforce. E-Document is outside of Salesforce. L-Document is on a Social Netork.
cVersion.PathOnClient = attach.Name;//File name with extention
cVersion.Origin = 'H';//C-Content Origin. H-Chatter Origin.
cVersion.OwnerId = attach.OwnerId;//Owner of the file
cVersion.Title = attach.Name;//Name of the file
cVersion.VersionData = attach.Body;//File content
Insert cVersion;

//After saved the Content Verison, get the ContentDocumentId
Id conDocument = [SELECT ContentDocumentId FROM ContentVersion WHERE Id =:cVersion.Id].ContentDocumentId;

//Insert ContentDocumentLink
ContentDocumentLink cDocLink = new ContentDocumentLink();
cDocLink.ContentDocumentId = conDocument;//Add ContentDocumentId
cDocLink.LinkedEntityId = attach.ParentId;//Add attachment parentId
cDocLink.ShareType = 'I';//V - Viewer permission. C - Collaborator permission. I - Inferred permission.
cDocLink.Visibility = 'InternalUsers';//AllUsers, InternalUsers, SharedUsers
Insert cDocLink; 
  • Do you have a middleware? one of the ideas is to pull these attachments into external storage from S3 and push it back to salesforce. Another option it to look at magic mover app – RedDevil Nov 14 '19 at 8:42

What is this custom logic you are referring to?

You will not be able to escape the heap size limit when processing attachment body's in apex as the data will consume the heap space for an attachment of size > 12MB during async apex (i.e. calculating base64 string of the body). Actually, your upper bound in cases like this is closer to ~10MB because of the rest of your apex logic taking up heap space as well.

Salesforce has a max size of 65MB on Attachments for orgs that requested an increase from the original 25MB.

Ideally you would use a conversion tool that doesn't rely on apex for the conversion (some sort of middleware) because other platforms don't have a hard limit around file processing like this.

  • @ Glen... no middleware right now.. Custom logic is regarding mapping of fields from attachment and its parent custom object to contentVersion record – Manjot Singh Nov 14 '19 at 10:19
  • I see - If you need parent data you need to aggregate somehow. I didn't mention but you could prep all this manually as well as long as you have storage for all the files you want to move. You can always export the binary files and then make the data mapping csv using the parent data as well (would take some dataloader + excel copy and pasting effort to aggregate into a single sheet) help.salesforce.com/… – Glen De Marcos Nov 14 '19 at 10:28

You have to use middleware if that's not possible then another way would be to move the code out of apex to Lightning Component aura or LWC and then use Salesforce Rest API to download attachments, convert them to files and upload it back into salesforce. It would be faster as your faster desktop would be used for processing.

The only drawback is you have to keep your browser open while running while doing this, unless you look into headless chrome and puppeteer to automate it for you.

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.