function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
RdRd 

Apex trigger fires, but doesn't always have the correct result

I have created a lookup field on the content version object that I am trying to auto populate whenever a file is uploaded on that object.

I created a trigger but it only works sometimes, and other times it doesn't.

This is the code that I have:

trigger UpdateCVLookup on ContentVersion (after insert) {
    
    Set<Id> contentDocumentIdSet = new Set<Id>();
    
    for(ContentVersion cv:trigger.new)
    {
        if(cv.ContentDocumentId != null)
        {
            contentDocumentIdSet.add(cv.ContentDocumentId);
        }
    }
    
    ContentDocumentLink cdl = [SELECT ContentDocumentId, LinkedEntityId FROM ContentDocumentLink WHERE ContentDocumentId IN:contentDocumentIdSet LIMIT 1];
 
    // Project__c can be replaced with the object that has the lookup relationship.

    List<Project__c> upList = [SELECT Id, name FROM Project__c where Id =:cdl.LinkedEntityId];   
    
    //In the following line, make sure to replace Project__c(The lookup field name) with the api name of the lookup field on the content version object.
    List<ContentVersion> cvList = [SELECT Id, Project__c, ContentDocumentId FROM ContentVersion where Id IN: Trigger.newMap.keySet()];
    
    for(ContentVersion cv:cvList)
    {
        if(upList.size() > 0)
        {//In the next line Project__c is referring to the lookup object.
            for(Project__c p : upList){
                //The following line Project__c is referring to the lookup field on Content Versions.
                cv.Project__c = p.Id; 
            }
        }
        else if(upList.size() > 0){
            //The next two lines containing Project__c are referring to the lookup field on Content Versions
            cv.Project__c = cdl.LinkedEntityId;
        } else {
            //This line below is required so that files can still be uploaded to other objects.
            cv.Project__c = null;
        }
    }
    update cvList;
}
Best Answer chosen by Rd
Abdul KhatriAbdul Khatri
Hi Randy,

I guess you might need to go through ContentDocumentLink and you can use the following code to handle what you want to do. The concept is the same that it does trigger whenever you upload a file but you have a more control there.

I tried with ContentVersion and I got issues getting the EntityLinkId for the Project instead I was getting it for the User and it failed when I tried to update the Lookup because of the Id descrepancy.
 
trigger ContentDocumentLinkProject on ContentDocumentLink (after insert) {
    Map<Id, Id> cdlEntityMap = new Map<Id, Id>();
	for(ContentDocumentLink cdl : trigger.new)       
	{
        if(cdl.LinkedEntityId.getSObjectType() == Project__c.getSObjectType())
    		cdlEntityMap.put(cdl.ContentDocumentId, cdl.LinkedEntityId);
	}
   
    if(cdlEntityMap.isEmpty()) return;
    
    List<ContentVersion> cvToUpdateList = new List<ContentVersion>();
	for(ContentVersion cv : [SELECT Id, ContentDocumentId, Project__c FROM ContentVersion WHERE ContentDocumentId = :cdlEntityMap.keySet()])
    {
        cv.Project__c = cdlEntityMap.get(cv.ContentDocumentId);
        cvToUpdateList.add(cv);
    }
    
    if(!cvToUpdateList.isEmpty()) update cvToUpdateList;
}

Let me know thoughts
 

All Answers

VinayVinay (Salesforce Developers) 
Hi Randy,

Try to check debug logs of working and non-working scenario that should narrow down issue.  

Thanks,
Vinay Kumar
Andrew GAndrew G
looking at your last if statement area
 
for(ContentVersion cv:cvList)
    {
        if(upList.size() > 0) {
//do stuff
        }
        else if(upList.size() > 0){
//do stuff
    }
    update cvList;
given that your test for uplist.size() is the same for both IF and ELSE components, the code in the ELSE will NEVER run

is that the source of the issue?

regards
Andrew
 
Abdul KhatriAbdul Khatri
Hi Randy,

I guess you might need to go through ContentDocumentLink and you can use the following code to handle what you want to do. The concept is the same that it does trigger whenever you upload a file but you have a more control there.

I tried with ContentVersion and I got issues getting the EntityLinkId for the Project instead I was getting it for the User and it failed when I tried to update the Lookup because of the Id descrepancy.
 
trigger ContentDocumentLinkProject on ContentDocumentLink (after insert) {
    Map<Id, Id> cdlEntityMap = new Map<Id, Id>();
	for(ContentDocumentLink cdl : trigger.new)       
	{
        if(cdl.LinkedEntityId.getSObjectType() == Project__c.getSObjectType())
    		cdlEntityMap.put(cdl.ContentDocumentId, cdl.LinkedEntityId);
	}
   
    if(cdlEntityMap.isEmpty()) return;
    
    List<ContentVersion> cvToUpdateList = new List<ContentVersion>();
	for(ContentVersion cv : [SELECT Id, ContentDocumentId, Project__c FROM ContentVersion WHERE ContentDocumentId = :cdlEntityMap.keySet()])
    {
        cv.Project__c = cdlEntityMap.get(cv.ContentDocumentId);
        cvToUpdateList.add(cv);
    }
    
    if(!cvToUpdateList.isEmpty()) update cvToUpdateList;
}

Let me know thoughts
 
This was selected as the best answer
RdRd
This worked perfectly, and that was the issue I was having where it would grab the User's id at times.

I didn't think I could do it on the content document link originally but this makes sense now.

Thank you!