2

I'm getting the "Too many SOQL queries: 101" when executing a test class. I'm not even getting into my test method - it's failing on the test setup. When it fails, it's failing in my trigger helper class. Specifically, the error message is:

Class.ContentDocumentLinkTriggerHelper.myTriggerMethod: line 18, column 1 Trigger.ContentDocumentLinkTrigger: line 3, column 1

I know code needs bulkification and not do SOQL inside for loops, and as far as I can see, I have bulkified, and I'm not doing SOQL in a loop. My trigger is before insert on ContentDocumentLink, and in my test setup method, I'm not even inserting into ContentDocumentLink - I'm only inserting into ContentVersion. I'm using a loop to create 201 ContentVersion records, adding each one to a list, and outside the loop inserting. (Trying to simulate what might happen if someone imports multiple records simultaneously.)

I think what's happening is when I insert the ContentVersion, Salesforce is automatically creating a ContentDocumentLink record (not unexpected), which fires my trigger. In my trigger helper class, I do have a SOQL statement outside the for loop, and I think it's bulkified, but the automatic ContentDocumentLink inserts Salesforce is doing are happening one at a time and not bulkified, causing my SOQL statement to execute multiple times, causing the error, but I can't figure out why.

Can anyone shed some light on what is happening? Is my test of trying to insert 201 ContentVersion records invalid? The code below is from a dev org, and you should be able to copy/paste into a dev org if you want and reproduce the issue. Just run the test method, and you should get the failure message.

My trigger:

trigger ContentDocumentLinkTrigger on ContentDocumentLink (before insert) {
    if (trigger.isBefore && trigger.isInsert) {
        ContentDocumentLinkTriggerHelper.myTriggerMethod(trigger.new);
    }
}

Trigger helper:

public with sharing class ContentDocumentLinkTriggerHelper {

    public static void myTriggerMethod(List<ContentDocumentLink> insertedContentDocLinks) {
        system.debug(insertedContentDocLinks);
        List<ContentDocumentLink> filteredContentDocLinks = new List<ContentDocumentLink>();
        List<String> contentDocumentIds = new List<String>();
        for (ContentDocumentLink contDocLink : insertedContentDocLinks) {
        
            string entityId = contDocLink.LinkedEntityId;
            if (entityId.left(3) == '005') {
                filteredContentDocLinks.add(contDocLink);
                contentDocumentIds.add(contDocLink.ContentDocumentId);
            }
        }

        system.debug('contentDocumentIds: ' + contentDocumentIds);
        // The below line is where the error is reported.
        List<ContentDocument> contentDocs = [select id, title, FileType from ContentDocument where id in :contentDocumentIds];
        //Map<Id, ContentDocument> contentDocumentMap = new Map<Id, ContentDocument>([select id, title, FileType from ContentDocument where id in :contentDocumentIds]);
    
        // Do other work here with filteredContentDocLinks
    }
}

Test class:

@isTest
public with sharing class ContentDocumentLinkTriggerHelperTest {

    @testSetup
    static void setupData(){
        Account a = new Account(
        Name = 'Test Account 1'
        );
        insert a;

        Opportunity o = new Opportunity(
            Name = 'Test Opportunity 1',
            AccountId = a.Id,
            CloseDate = Date.newInstance(2022, 07, 22),
            StageName = 'Prospecting'
        );
        insert o;

        List<ContentVersion> contentVersions = new List<ContentVersion>();
        for (Integer i = 1; i <= 201; i++) {
            String fileExt = '.pdf';
            if (i <= 100) {
                fileExt = '.docx';
            }

            ContentVersion contentVersion = new ContentVersion(
                Title          = 'Invoice 2022-07-09 - ' + String.valueOf(i) + fileExt,
                PathOnClient   = 'Invoice 2022-07-09 - ' + String.valueOf(i) + fileExt,
                VersionData    = Blob.valueOf('This is my sample content - ' + String.valueOf(i)),
                IsMajorVersion = true
            );
        
            contentVersions.add(contentVersion);
        }
        system.debug('inserting contentVersions');
        insert contentVersions;
    }

    @isTest
    static void myTestMethod() {

        system.assertEquals(1, 1, 'Fake Message');
    
    }
}

1 Answer 1

3

For each content version getting inserted, Salesforce creates a Content document link record in backend on the running user, which surprisingly triggers Content Document link trigger one by one. This creation is not handled in a bulk.

This is internal to SF and cannot be controlled.

If you see the logs in finest level you would be able to find this behaviour.

enter image description here

4
  • So my theory was correct. Good to know for the future. And I didn't think of setting the logs to finest, but that makes sense.
    – Jeff
    Jul 16, 2022 at 11:34
  • question: do you know or think this is an issue in Salesforce that should be reported to Salesforce or functioning as designed? If it's an issue, I will see about reporting it.
    – Jeff
    Jul 18, 2022 at 13:58
  • 1
    This may be an issue, for sure, you can definitely raise it. But this issue is a known issue and has been there for years, Take a look here if you want to test the fucntionality in bulk manner. salesforce.stackexchange.com/questions/245491/… Jul 18, 2022 at 14:22
  • I didn't find the question you referenced when posting mine - I wish I had. I guess my search skills (or reading comprehension) are lacking. But given that the post you linked has a link to a Salesforce page noting the behavior, it seems pointless to raise the issue again. Thanks for your quick responses!
    – Jeff
    Jul 18, 2022 at 14:31

You must log in to answer this question.

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