5

I have a custom app that is used for scheduling face-to-face trainings. I'm trying to set up a class that will run daily to gather all trainings scheduled for the next two weeks, and send out training materials in the form of content packs.

I have a custom object, Content_Mapping__c, that ties product record ids to content version record ids. Scheduling is done from a custom object, tracker_record__c (as in Fulfillment Tracker).

    date twoWks = system.today().addDays(14);

    //maps product id to content map record
    map<id, content_mapping__c> conMap = new map<id, content_mapping__c>();

    conDis = new list<ContentDistribution>();

    //list of trainings in the next two weeks for which materials have not been sent
    trList = [SELECT product__r.id, school_district__r.name, comparison_date__c FROM tracker_record__c WHERE comparison_date__c >= :date.today() and comparison_date__c <= :twoWks and materials_sent__c = FALSE and (product_type__c = 'Onsite Training - Full Day' or product_type__c = 'Onsite Training - Half Day')];

    if(trList.size() > 0){
        for(content_mapping__c cm : [SELECT product__r.id, ContentVersionID__c, ContentDocumentID__c FROM content_mapping__c WHERE ContentDocumentID__c != NULL and ContentVersionID__c != NULL]){
            system.debug(cm.product__r.id);
            conMap.put(cm.product__r.id,cm);
        }

        for(tracker_record__c tr : trList){

            //make sure product has materials mapped to it
            if(conMap.get(tr.product__r.id) != NULL ){

                //create content distribution for each tracker record
                ContentDistribution cd = new ContentDistribution();
                cd.Name = 'test';
                cd.ContentVersionId = conMap.get(tr.product__r.id).ContentVersionID__c;
                cd.PreferencesAllowOriginalDownload = true;
                cd.PreferencesAllowPDFDownload = true;
                cd.PreferencesAllowViewInBrowser = true;
                cd.ExpiryDate = tr.Comparison_Date__c.addDays(2);
                cd.PreferencesExpires = true;
                cd.RelatedRecordId = tr.id;
                conDis.add(cd);
            }
        }

        insert conDis;

This fails every time at the insert, with a DUPLICATE_VALUE error on unknown fields for unknown records. Any advice?

UPDATE:

This is my full code I'm running in the dev console.

date twoWks = system.today().addDays(14);

list<tracker_record__c> trList = [SELECT product__r.id, school_district__r.name, comparison_date__c FROM tracker_record__c WHERE comparison_date__c >= :date.today() and comparison_date__c <= :twoWks and materials_sent__c = FALSE and (product_type__c = 'Onsite Training - Full Day' or product_type__c = 'Onsite Training - Half Day')];
list<contentDistribution> conDis = new list<ContentDistribution>();

map<id, content_mapping__c> conMap = new map<id, content_mapping__c>();

if(trList.size() > 0){
    list<content_mapping__c> cm = [SELECT product__r.id, ContentVersionID__c, ContentDocumentID__c FROM content_mapping__c WHERE ContentDocumentID__c != NULL and ContentVersionID__c != NULL];
    for(content_mapping__c c : cm ){
        system.debug(c.product__r.id);
        conMap.put(c.product__r.id,c);
    }

    integer counter = 1;
    for(tracker_record__c tr : trList){
        if(conMap.get(tr.product__r.id) != NULL){
            //create content distribution for each tracker record
            ContentDistribution cd = new ContentDistribution();
            cd.Name = 'test'+counter;
            system.debug(cd.name);
            counter++;
            system.debug(tr.product__r.id);
            cd.ContentVersionId = conMap.get(tr.product__r.id).ContentVersionID__c;
            cd.PreferencesAllowOriginalDownload = true;
            cd.PreferencesAllowPDFDownload = true;
            cd.PreferencesAllowViewInBrowser = true;
            cd.ExpiryDate = tr.Comparison_Date__c.addDays(2);
            cd.PreferencesExpires = true;
            cd.relatedRecordId = tr.id;
            conDis.add(cd);
            system.debug(cd);
        }
    }
insert conDis;
}

And the error:

14:09:09.109 (109319129)|DML_BEGIN|[36]|Op:Insert|Type:ContentDistribution|Rows:2 14:09:09.337 (337716128)|DML_END|[36] 14:09:09.337 (337827278)|EXCEPTION_THROWN|[36]|System.DmlException: Insert failed. First exception on row 1; first error: DUPLICATE_VALUE, duplicate value found: duplicates value on record with id: : [] 14:09:09.338 (338308565)|FATAL_ERROR|System.DmlException: Insert failed. First exception on row 1; first error: DUPLICATE_VALUE, duplicate value found: duplicates value on record with id: : []

Here are the two contentDistribution records that are failing on insert:

DEBUG|ContentDistribution:{Name=test1, ContentVersionId=068m00000009X4zAAE, PreferencesAllowOriginalDownload=true, PreferencesAllowPDFDownload=true, PreferencesAllowViewInBrowser=true, ExpiryDate=2015-06-21 00:00:00, PreferencesExpires=true, RelatedRecordId=a4S60000000L1cgEAC}

DEBUG|ContentDistribution:{Name=test2, ContentVersionId=068m00000009X4zAAE, PreferencesAllowOriginalDownload=true, PreferencesAllowPDFDownload=true, PreferencesAllowViewInBrowser=true, ExpiryDate=2015-06-20 00:00:00, PreferencesExpires=true, RelatedRecordId=a4S60000000KztXEAS}

  • 3
    If Name is a unique field then you would get that error every time because you are setting it to test. Check ContentDistribution to see what fields are unique. – BarCotter Jun 12 '15 at 14:37
  • 1
    you can add an increment counter to the name and test does the error still kick off or not. – Suresh Jun 12 '15 at 14:56
  • Thanks for the comments. Unfortunately, making the contentDistribution name unique is still giving the same error. – Jason Kelley Jun 12 '15 at 18:10
  • integer counter = 1; for(tracker_record__c tr : trList){ if(conMap.get(tr.product__r.id) != NULL){ //create content distribution for each tracker record ContentDistribution cd = new ContentDistribution(); cd.Name = 'test'+counter; system.debug(cd.name); counter++; – Jason Kelley Jun 12 '15 at 18:10
3

I was just running into this issue as well and it appears to be a bug on Salesforce's side. If you insert the ContentDistribution records one at a time it succeeds. Of course that might not be feasible depending on how many you need to insert.

I created a support case a while back and this is the response I received:

Just wanted to share the update by R&D team. The behavior is Working as Designed however it is not documented anywhere. Thus, they have made a note to share the information with our technical writer to update that ContentDistribution cannot be updated within a second. To simultaneously insert multiple content distribution records, you need to have different content version Ids.

  • Jeff - Thank you for chiming in, if for no other reason than to confirm I'm not crazy. :-) When you're inserting the Content Distribution records, how are you doing it exactly? I haven't touched this project in about six weeks, but from what I remember, when I looped over the list of ContentDistribution records I had been trying to bulk insert and instead executed individual DML statements in the loop, I got the same error. – Jason Kelley Jul 18 '15 at 18:23
  • Have you found the solution for it? I'm afraid I'm encountering the same error and suspect bulk insert might be the cause of the error. Is it still the case? – Nawshine Feb 24 '16 at 4:35
  • @JasonKelley Sorry, it looks like I missed your comment. At one point I thought I had it working with separate DMLs in one context, but then I was looking at it again later and it wasn't working, so I must have been mistaken. – Jeff Mar 2 '16 at 2:56
  • @Nawshine I've updated my answer with the response I received from Salesforce support. Unfortunately it only confirms that this is not supported. – Jeff Mar 2 '16 at 3:09
  • 1
    @Nawshine I didn't get it working as intended, but I succeeded in a work around. As I said in my original post, I use content deliveries to share training materials for my company's face-to-face training products. Instead of creating individual content deliveries per customer, I create one delivery per content pack and share that with all customers that need it. I have a class that runs every morning, creates the content deliveries and emails links out to our customers and trainers. – Jason Kelley Mar 3 '16 at 13:33
1

I suspect your problem may be here:

if(trList.size() > 0){
    for(content_mapping__c cm : [SELECT product__r.id, ContentVersionID__c, ContentDocumentID__c FROM content_mapping__c WHERE ContentDocumentID__c != NULL and ContentVersionID__c != NULL]){
        system.debug(cm.product__r.id);
        conMap.put(cm.product__r.id,cm);
    }

The query for content_mapping__c cm shouldn't be inside the for loop. Otherwise, I think you have a mismatch in brackets someplace. It would seem that the for loop should follow the query to put the contents inside ConMap as below:

if(trList.size() > 0){
    list<content_mapping__c> cm = [SELECT product__r.id, ContentVersionID__c, ContentDocumentID__c FROM content_mapping__c WHERE ContentDocumentID__c != NULL and ContentVersionID__c != NULL];
    for(contact_mapping__c c:cm){
        system.debug(c.product__r.id);
        conMap.put(c.product__r.id,c);
    }
  • Thank you for your response and answer. I made this change (updated my original post), but unfortunately it's still throwing the same error. – Jason Kelley Jun 12 '15 at 18:19
  • 1
    One of the issues that I see is that your query for cm isn't constrained to include the product__r.id from trList in it's WHERE clause. Wouldn't those be the product__r.id's that you're looking for? – crmprogdev Jun 12 '15 at 20:06
  • Thank you for following up. Yes, the records i want from Content_Mapping__c would be only those product ids referenced in trList. I initially had added those ids to a set, and included that set in the cm query WHERE clause. Once I was encountering this persistant error I couldn't remedy, I wound up deleting my test data out of the Content_Mapping__c object. It currently has only two records. I thought with a very small controlled group I might be able to figure out where my issues were a little easier. That's when I removed the set and just queried all records from Content_Mapping__c. – Jason Kelley Jun 12 '15 at 20:23

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.