Take the 2-minute tour ×
Salesforce Stack Exchange is a question and answer site for Salesforce administrators, implementation experts, developers and anybody in-between. It's 100% free, no registration required.

I have a weird situation going on and I am not able to understand why? Here is my scenario

I will try to provide a simple example,

I have an Apex class inserting a Contact, I am referencing a Visualforce Page from the same apex class using newly inserted Contact Id. but the newly inserted Contact is not found in the Visualforce Page Controller.

Apex Class I am executing -

public class Parallelism{

    public void insertContact(String acctId){
        Contact newCon = new Contact(LastName='Testing',FirstName='Parallels',AccountId=acctId);

        insert newCon;        

        Pagereference pPage = Page.ParallelismPage; // this is the problem part.
        pPage.getParameters().put('id',newCon.Id);
        Blob attBody = pPage.getContentAsPDf();

        Attachment att  = new Attachment();
        att.ParentId    = acctId;
        att.Body        = attBody;
        att.Name        = 'Testing Parallelism';
        att.ContentType = 'application/pdf';

        insert att;

        //Parallelism.lookupContactInFuture(acctId);

        doSomethingElseWithContact(newCon);  
    }

    private void doSomethingElseWithContact(Contact newCon){
        system.debug('Thread 1 ' + newCon.LastName + ' ' + newCon.FirstName);   
    }

    @future
    public static void lookupContactInFuture(String acctId){

        try {
            Contact found = [Select Id, LastName, FirstName 
                             from Contact 
                             where AccountId = :acctId 
                             order by CreatedDate desc 
                             LIMIT 1];

            system.debug('Thread 2 ' + found.LastName + ' ' + found.FirstName);        
        }catch(exception e){
            system.debug('Parallelism failed in Thread 2');
        }
    }
}

Visualforce Page

<apex:page controller="ParallelismCompCon">
<apex:outputPanel rendered="{!showData}">
        <apex:outputText value="Parallel Visualforce Component - {!found.LastName}"/>
    </apex:outputPanel>
    <apex:outputPanel rendered="{!NOT(showData)}">
        <apex:outputText value="Parallel Visualforce Component - failed"/>
    </apex:outputPanel>
</apex:page>

Controller class -

 public class ParallelismCompCon{

    public boolean showData {get;set;}
    public Contact found    {get;set;}
    public id contactId     {get;set;}

    public ParallelismCompCon(){
        showData = false;
        contactId = Apexpages.currentPage().getParameters().get('id');      
        showData = processContact();
    }

    public boolean processContact(){

        try {
            found = [Select Id, LastName,FirstName from Contact where Id = :contactId order by CreatedDate desc LIMIT 1];

            system.debug('Thread 2 ' + found.LastName + ' ' + found.FirstName);
            return true;

        }catch(exception e){
            system.debug('Visualforce Component failed in Thread 2');
            return false;
        }
    }
}

Well, the future method works fine, but the Page doesn't find the contact, Can anyone explain this behavior? Appreciate it thank you.

share|improve this question
    
By the way I also tested with Pagereference pPage = new Pagereference('/apex/ParallelismPage'); –  logontokartik Apr 11 at 15:40

2 Answers 2

up vote 2 down vote accepted

You're crossing a transaction boundary when you kick off the Apex controller, and that controller doesn't see the record you just inserted. As far as I can see, you'll have to either

  • Create the PDF asynchronously
  • Create the record in the second controller
  • Serialize the newly created object into a JSON string, pass that string as a query parameter to the next VF page, deserialize the string back into the required object in the page controller's constructor
  • Re-architect in some other way so that record and PDF creation happen in the same transaction
share|improve this answer
    
Thanks you for options. I think I need to figure out a way to do the 2nd option in that case, as we have a limitation of getContent() not working in future methods. which is most important one for me. –  logontokartik Apr 11 at 20:48

You set the parameter "id" to the Contact id in the Parallelism class but do not pickup that value in the ParallelismCompCon class so are querying using a null contactId.

(The "id" parameter is more automatically handled when you write a standard controller extension, but when you write a purely custom controller you have to do the parameter handling yourself.)

share|improve this answer
    
Sorry for missing that, my code was more complex, so I setup simple example, Its definitely not picking up the id causing the issue. I added the code and still same result. –  logontokartik Apr 11 at 15:06
    
OK. As you are creating the new page within the first controller I would have thought the second controller would be within the same transaction and so able to see the new contact even though the transaction has not committed. Hopefully someone else can explain it. –  Keith C Apr 11 at 15:18
1  
@logontokartik You are also leaving showData uninitialized so the page output will be wrong. –  Keith C Apr 11 at 15:29
    
true. but here is a food for thought, if I execute a future method from the Parallelism Class, I am able to find the Contact. Though the future is not really a parallel transaction, its asynchronous right, so the contact might be found or might not, maybe depends on the transaction its called from, for it to commit first? –  logontokartik Apr 11 at 15:30
    
@logontokartik I believe that the future isn't scheduled until the transaction it was created in commits so with your code the future should always be able to query successfully. I understand your issue to be in the second controller though not the future method. –  Keith C Apr 11 at 15:33

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.