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
rtuttlertuttle 

Working around "This page uses a QueryLocator that is invalid" error

Has anyone figured a way to work around this error when instantiating using a StandardSetController with a QueryLocator?  I've tried creating a get method for the controller object that pulls a record inside of a try catch block, but this error seems to happen before the controller is ever touched.

 

Edit:  This only happens after 15 minutes of idle usage.  If after that point someone tries to call a method on the StandardSetController it throws an uncatchable exception.

 

Here is what I attempted to catch this exception to no avail:

 

 

public ApexPages.StandardSetController controller {

get {

if(this.controller!=null) {

try {

//Integer x = controller.getPageSize(); // attempt to trigger the timed out query locator exception

SObject s = controller.getRecords()[0];

return controller;

} catch(Exception e) {

System.debug(LoggingLevel.INFO,e.getMessage());

}

}

String parentId = QuickCaseUtil.getParameter('id');

if(parentId != '') {

this.controller = new ApexPages.StandardSetController(Database.getQueryLocator([SELECT CreatedDate, Content__c,Identifier__c,Title__c,ThreadType__c FROM CaseThread__c WHERE Case__c = :parentId ORDER BY CreatedDate DESC]));

} else {

this.controller = null;

}

return controller;

}

set;

}

 

 Edit:  Fixed code box which seems to hate Chrome

 

Message Edited by rtuttle on 02-18-2010 01:46 PM
Message Edited by rtuttle on 02-22-2010 02:48 PM
Message Edited by rtuttle on 02-22-2010 02:48 PM
cloudcodercloudcoder

I think you may be missing something in your overall design. It is a little hard to tell from the snippet what else in your code is using your controller. There is a complete example on using the StandardSetController in the docs that should help.

I also used the salient bits of your code to see if the exception was getting thrown when using a generic StandardSetController through Visualforce (I made the assumption that was what you were doing in the rest of your code. Again, no exception was thrown so I suspect the issue is in your query.

 

 

 Controller Extension:

 

 

public class DrakoExtension{ public ApexPages.StandardSetController myController { get { if(this.myController != null) { SObject s = myController.getRecords()[0]; } else { this.myController = new ApexPages.StandardSetController(Database.getQueryLocator([Select id, name from Account])); } return myController; } set; } public DrakoExtension(ApexPages.StandardController stdController) {}}

 

 

Visualforce Page:

 

 

<apex:page standardController="Account" extensions="DrakoExtension"> {!myController} <p/></apex:page>

 

 

 

rtuttlertuttle

Thanks for taking a look at this.  After reading this I poked around a little more and noticed I don't have to use a QueryLocator to do what I was intending.  The use case is for a paginated list of case thread custom objects.  So it seems like I won't need a QueryLocator since the amount of thread objects will be minimal.

 

The issue still seems odd to me that you cannot catch this exception in the page controller when accessing the set controller.  I did come up with a workaround which I won't need to use at this point.  The concept is to use an actionfunction tied to a method called keepAlive, which would store the page then change to the page.  This would be called from a timer in javascript inside the rerendered outputpanel of the paginated data.  I haven't tested, so I'm not positive this workaround would work.

 

It still seems to me that you should be able to catch this exception if the set controller is ever used in visualforce.  What if this was a set controller that pulled in a few hundred thousand records that had to be filtered to specific accounts and the end user walked away for a 20 minute break?  They would get an extremely ugly error page that the developer couldn't catch.

 

Thanks a ton for looking at this cloudcoder, thankfully my use case allows for me to not have to use the QueryLocator. 

 

 

 

-Richard 

rtuttlertuttle

Okay, so I switched to using a standard query instead of a QueryLocator and now the StandardSetController doesn't paginate the data.  When accessing the getRecords() method it returns all results even if I've set the page size via setPageSize(10).

 

The strange thing is the pagination info works great, it knows the page it should be on and the proper amount of records per page.  Only the StandardSetController.getRecords() method seems to be having an issue.

 

 

-Richard 

cloudcodercloudcoder

That is correct. QueryLocator provides the pagination, and fetches the data intelligently which you call MyStandardSetController.next(). For example, the code below will return '5':

 

 

ApexPages.StandardSetController ssc = new ApexPages.StandardSetController(Database.getQueryLocator([SELECT name,closedate FROM Opportunity]));ssc.setPageSize(5);ssc.getRecords().size();

 

 

 

 

You should certainly take advantage of instantiating  your StandardSetControllers using QueryLocators. I know your initial question was that you were experiencing exception when using them. Check out my previous response for removing that error.

 

 

rtuttlertuttle

cloudcoder,

 

To replicate the exception try that same test code you provided in the first example, but add a next button on the page that calls myController.next as an action.  Let the page sit for 15 minutes+ and then click next.  You receive an exception which cannot be caught in the apex.

 

 

-Richard 

 

 

 

 

rtuttlertuttle
I added an edit comment to the initial post, and changed wording in the opening line.  I don't think I was being very clear about where the exception occurs at the time I initially posted this thread.  It was a Friday, my brain and communication skills had already left for the day :)