0

I have a trigger that I need to deploy urgently to our org. The trigger works perfectly however running the test gives a null object error, I have created the object and assigned all the correct variables, however, I cannot see why it is empty.

Could it be the execution order or something similar?

Error is :

System.DmlException: Insert failed. First exception on row 0; first

error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, ContentVersionParentUpdate: execution of AfterInsert

caused by: System.NullPointerException: Attempt to de-reference a null object

Trigger.ContentVersionParentUpdate: line 31, column 1: []

Trigger

    trigger ContentVersionParentUpdate on ContentVersion (After insert) {

         // create a set of all the unique opportunity ids for SOQL below
    Set<id> ContentdocumetIds = new set<id>();

    for (ContentVersion CV1 : Trigger.new){
         ContentdocumetIds.add(CV1.ContentDocumentId);
    }

    System.debug(ContentdocumetIds);

     // create a map so that Opportunity is locatable by its Id (key)
     // 
    Map<string, contentdocumentlink> myMap = new Map<string, contentdocumentlink>(); 

    for(contentdocumentlink objCS : [Select z.linkedentityid, z.contentdocumentid From contentdocumentlink z WHERE contentdocumentid IN :ContentdocumetIds AND LinkedEntityId IN
        (SELECT Id FROM Opportunity)] )

    myMap.put(objCS.contentdocumentid, objCS);

    System.debug(myMap);



    For (ContentVersion CV1 :trigger.new){

        //System.debug('Linkedid pre second loop' + myMap.get(CV1.ContentDocumentId).linkedentityid);

    contentversion CV2 = [Select id,ContentDocumentId from Contentversion where id = :cv1.Id];

        System.debug('Linkedid' + myMap.get(CV2.ContentDocumentId).linkedentityid); 

        if(myMap.get(CV2.ContentDocumentId).linkedentityid.getSObjectType() == Schema.Opportunity.getSObjectType()){

        Cv2.AssociatedOppLinkID__c = myMap.get(CV2.ContentDocumentId).linkedentityid;

            update CV2;
        }
    }

}

Test

@istest
public class ContentVersionParentUpdateTest {

    Public Static Testmethod void Inserttest1(){

        //List<Campaign>  Campaign = [Select id From Campaign Limit 1];

        //RecordType ContentRT = [select Id FROM RecordType WHERE sObjectType ='ContentVersion' Limit 1];
        //

        Campaign CMP = New Campaign();
        CMP.Name = 'TestCMP';

        Insert CMP;

        //Create new account to associte the primary opportunity to

        Account Acc = New Account();
        Acc.Name = 'ContentVersionTestAccount';
        Acc.Type = 'Customer';
        //Acc.RecordTypeId = [Select Id From RecordType Where sObjectType = 'Account' Limit 1];

        Insert Acc;

        //Create Contact to be PrimaryContact on Opportunity

        Contact Cont = New Contact();
        Cont.LastName = 'Tester';
        Cont.AccountId = Acc.Id;

        Insert Cont;

        //New Opportunity to be the linkedentityid on the ContentDocumentLink

        Opportunity Opp = New Opportunity();            
        Opp.Name = Acc.Name + ' Opportunity';           
        Opp.StageName = 'Discovery';
        Opp.Type = 'Up-Selling';
        Opp.AccountId = acc.Id;
        Opp.Primary_Contact__c = Cont.Id;
        Opp.CampaignId = CMP.id;
        Opp.CloseDate = Date.today() + 10;
        Opp.CurrencyIsoCode = 'GBP';
        Opp.LeadSource = 'Other';

        Insert Opp;




        Test.startTest();

        ContentVersion TestContentVersionInsert = New ContentVersion();
        TestContentVersionInsert.ContentUrl = 'https://www.google.co.uk/?gfe_rd=cr&ei=r4aUWdjGC4rW8AeVvJywDg';
        TestContentVersionInsert.Title = 'Google';

        insert TestContentVersionInsert;

        Set<id> ContentdocumetIds = new set<id>();

        Set<ContentVersion> ContentVersion = new set<ContentVersion>();

        ContentVersion.add(TestContentVersionInsert);

        ContentdocumetIds.add(TestContentVersionInsert.Id);


        Contentdocumentlink TestContentDocumentLinkInsert = New ContentDocumentLink();
        TestContentDocumentLinkInsert.ContentDocumentId = TestContentVersionInsert.Id;
        TestContentDocumentLinkInsert.LinkedEntityId = Opp.Id;
        TestContentDocumentLinkInsert.Visibility = 'V';

        Insert TestContentDocumentLinkInsert;

        Map<string, contentdocumentlink> myMap = new Map<string, contentdocumentlink>(); 

        for(contentdocumentlink objCS : [Select z.linkedentityid, z.contentdocumentid From contentdocumentlink z WHERE contentdocumentid IN :ContentdocumetIds AND LinkedEntityId IN
        (SELECT Id FROM Opportunity)] )

        myMap.put(objCS.contentdocumentid, objCS);

        For (ContentVersion CV1 :ContentVersion){

        //System.debug('Linkedid pre second loop' + myMap.get(CV1.ContentDocumentId).linkedentityid);

        contentversion CV2 = [Select id,ContentDocumentId from Contentversion where id = :cv1.Id];

        System.debug('Linkedid' + myMap.get(CV2.ContentDocumentId).linkedentityid); 

        if(myMap.get(CV2.ContentDocumentId).linkedentityid.getSObjectType() == Schema.Opportunity.getSObjectType()){

        Cv2.AssociatedOppLinkID__c = myMap.get(CV2.ContentDocumentId).linkedentityid;

        update CV2;


        Contentdocumentlink Linktest = [Select id from ContentDocumentLink where Contentdocumentid = :TestContentVersionInsert.Id];

        System.debug(linktest.ContentDocumentId );

        Test.stopTest();

    }

}
    }
}
1
  • 1
    What is line 31. That is the least of your problems btw. Your code breaks several rules and will cause you problems once in place
    – Eric
    Aug 16 '17 at 19:15
3

This looks like line 31:

System.debug('Linkedid' + myMap.get(CV2.ContentDocumentId).linkedentityid);

so if that is correct the problem is that myMap doesn't have an entry for CV2.ContentDocumentId. So you need to think about the various relationships and ensure you don't generate that situation in your code.

You don't need this query that will cause your code to break in the bulk case:

contentversion CV2 = [...];

as you can just reference CV1.ContentDocumentId instead as all fields are automatically provided for the trigger object.

4
  • The CV2 query was the only recommended way to update a record with details when it was read only after insert, my issue is that the test class doesnt seem to populate mymap when real life testing does
    – user37980
    Aug 16 '17 at 19:23
  • @user37980 FYI You don't need to query first to update, you can new contentversion(Id = CV1.Id) instead and then update. On the NPE, then it sounds like your test isn't wiring up the relationships as it should.
    – Keith C
    Aug 16 '17 at 20:30
  • I managed to correct all my errors and follow best practice on your advice, thank you
    – user37980
    Aug 22 '17 at 17:18
  • @user37980 Glad you got it sorted.
    – Keith C
    Aug 22 '17 at 18:13

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.