1

I am trying to generate multiple documents(which are VF page rendered as Word doc), by iterating over a map. As my first step, i am reading a report, generating a map(where key is a string and value is a List of DTO that i created) out of it and then save each key value pair as a record in a custom object. Below is code for this :-

   ReadReportsData runReport = new ReadReportsData();
    grpBasedMap = runReport.readReportData();

    List<Test_Data__c> dataToInsertList = new List<Test_Data__c>();

    for(String str : grpBasedMap.keySet()){
       Test_Data__c cd = new Test_Data__c();
       cd.group_number__c = grpNbr;
       List<myDTO> dtoList = grpBasedMap.get(str);
       cd.Data_To_Populate_Json__c = JSON.serialize(dtoList);
       censusDataToInsertList.add(cd);

    }

     insert censusDataToInsertList;
     List<Messaging.SingleEmailMessage> mails = new    List<Messaging.SingleEmailMessage>();

      for(String grpNbr : grpBasedMap.keySet()){
           mails.add(generateMail(grpNbr));            
        } 

Once the records get inserted, i am triggering another method that generates the documents by calling getContent() method on the VF page reference. Code is as below :-

public Messaging.SingleEmailMessage generateMail(String grpNbr){

   Messaging.SingleEmailMessage email = new Messaging.SingleEmailMessage(); 


       // Reference the attachment page 
       PageReference wordDoc =  Page.DataAsAttachment;
       wordDoc.getParameters().put('grpNo',grpNbr);

       wordDoc.setRedirect(true);       

       // Take the Word content
       Blob b = wordDoc.getContent();

       // Create the email attachment
       Messaging.EmailFileAttachment efa = new Messaging.EmailFileAttachment();
       efa.setFileName('Request.doc');
       efa.setBody(b);

       List<String> toAddresses = new List<String>{'naveen.rawat@test.com'};

       // Sets the paramaters of the email
       email.setSubject( 'Request' );
       email.setToAddresses(toAddresses );
       email.setHtmlBody(body);

       email.setFileAttachments(new Messaging.EmailFileAttachment[] {efa});

    return email;

}

In my VF page controller page when i query the inserted records an exception is thrown as below :- System.QueryException: List has no rows for assignment to SObject.

Which is now I understand is because of the transaction scope, as on the single transaction I am inserting the record and getting the record, I referred this Fields missing using getContent call for Visualforce rendered as PDF.

But how do i make sure that these request runs in separate transactions as i don't have any VF page component to define that.

I am thinking of handling the email logic in AFTER insert trigger of the Test_Data__c sObject. Thoughts and/or suggestions?

  • The link you reference includes a solution to the problem. Each request to the server is a separate transaction, and when the commandButton operation completes (and so has its transaction committed), its oncomplete attribute is used to make a second request to generate the PDF and that request can access the committed data. (Triggers won't help: they run in the same transaction.) – Keith C Jul 14 '15 at 20:58
  • that's where i have problem is, that i don't have that kind of commandbutton where i can then do the onComplete action. i am just running my code via Execute Anonymous Window. – NaveenRaw Jul 14 '15 at 21:08
  • It will take 10 minutes to create a Visualforce page contain the command button and a controller to wrap your logic and then you can use the "known good" solution. – Keith C Jul 14 '15 at 21:13
  • Thanks Keith. I was trying to resist creating a VF page and look for possibly other workarounds. Now I am gonna go ahead with your advice. – NaveenRaw Jul 14 '15 at 21:17
  • Sometimes a page is needed to run/test code. Another example is when making web service callouts. Here given that you can't commit a transaction in Apex code, using the browser to make two requests is the simplest solution. – Keith C Jul 14 '15 at 21:24
0

By executing my logic from a command button I am able to do the required functionality. I am now calling the method containing getContent() call on the onComplete() event of the Button as suggested in the following link.

Fields missing using getContent call for Visualforce rendered as PDF

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.