[SalesForce] StandardSetController List Instatiation and setFilterId

I'm having an issue using a List to instantiate the StandardSetController and applying a list view filter id.

Here's an example of using a List for instantiation as detailed at http://www.salesforce.com/us/developer/docs/pages/Content/apex_pages_standardsetcontroller.htm

        List<Campaign> campaigns = [SELECT Id FROM Campaign LIMIT 10000];
        ApexPages.StandardSetController ssc = new ApexPages.StandardSetController(campaigns);
        system.debug('standard set controller count before filter: '+ssc.getResultSize());
        ssc.setFilterId('00BU0000002L6POMA0');
        system.debug(ssc.getFilterId());
        system.debug('standard set controller count after filter: '+ssc.getResultSize());

The result of this is:

18:12:09:176 USER_DEBUG [17]|DEBUG|standard set controller count before filter: 10000
18:12:09:177 USER_DEBUG [19]|DEBUG|00BU0000002L6POMA0
18:12:09:177 USER_DEBUG [20]|DEBUG|standard set controller count after filter: 10000

'00BU0000002L6POMA0' is the id of a valid list view filter that should return two results according to the UI as well as my investigation in the org.

However, the filter is appropriately applied if I use the queryLocator method of instantiation.

        ApexPages.StandardSetController ssc = new ApexPages.StandardSetController(Database.getQueryLocator([SELECT Id FROM Campaign LIMIT 10000]));
        system.debug('standard set controller count before filter: '+ssc.getResultSize());
        ssc.setFilterId('00BU0000002L6POMA0');
        system.debug(ssc.getFilterId());
        system.debug('standard set controller count after filter: '+ssc.getResultSize());

results in:

18:17:37:233 USER_DEBUG [17]|DEBUG|standard set controller count before filter: 10000
18:17:37:319 USER_DEBUG [19]|DEBUG|00BU0000002L6POMA0
18:17:37:319 USER_DEBUG [20]|DEBUG|standard set controller count after filter: 2

Has anyone seen this and overcome it somehow?

The reason I would like to use the List instantiation is that it gets me around the nasty "Too many query locator rows: 10001" when I loop the StandardSetController instantiation a couple times to boost the # of records I can filter and return.

Best Answer

I think utilising the List View UI to allow your users to reuse this part of the platform is a great design decision btw! I've used this approach before and can tell you it does not matter what the original record set you select with your query selector is, so you can in fact use LIMIT 1.

However, unfortunately the StandardSetController will only handle 10,000 rows regardless, check out the documentation for the StandardSetController.getCompleteResult method.

"Indicates whether there are more records in the set than the maximum record limit. If this is false, there are more records than you can process using the list controller. The maximum record limit is 10,000 records."

So at least this method does let you inform the users that the results your showing them are truncated and thus ask them to refine their selection criteria.

If thats not going to be good enough for them or you, then you could utilise the Metadata API to retrieve the ListView definition and roll your own SOQL query. I've recently done this in Java for a DF12 presentation here. If you want to do this in Apex you can also utilise the Apex Metadata API library here. Let me know if you want to this route we could build a sample here together.