27

As per Visualforce Limits:

Maximum number of collection items that can be iterated in an iteration component such as <apex:pageBlockTable> and <apex:repeat> -- 1,000

So normally 1,000 is the limit. If try to iterate over more than 1,000 items then we receive this error:

collection size exceeds maximum size error

I observe when we use List<Sobject> variable to iterate over apex:repeat then we get this(collection size exceeds maximum size) error. But when I use Map<Id, Sobject> then I can iterate over more than 10,000 records (I tested with 20,000 records).

Noted: You can only iterate over 20,000 if view state does not exceed 135 KB

My Conclusion: It looks like this limitation doesn't apply on Map<Id, Sobject>.

I tried to find documentation related to this issue, but could find nothing. It doesn't seem like Salesforce's official documentation mentions it anywhere.

So what is the reason map doesn't hit the limit? Looks like a Salesforce hidden secret, or I am just imagining things?

Adrian Larson
  • 149,971
  • 38
  • 239
  • 420
Ratan Paul
  • 22,663
  • 13
  • 52
  • 97
  • 1
    if the map were transient; how high can you iterate? Of course, map key iteration will generate rows in no particular useful order so client side sorting might be required – cropredy Mar 30 '16 at 17:04
  • 1
    This is part of what Query More and Pagination is for. Stop and think about it, who want to see a page with 10k or 20k records all at once?? Even 1k of records is more than a person can reasonably be expected to digest at one time. If you want to output them to a file, you can do that in many different ways without needing to display them in a single view. – crmprogdev Mar 30 '16 at 17:28
  • @crmprogdev Yes..... no one wants to view so many records in page. but we can use this for jquery table like (DATATABLE](datatables.net)..so this way person can view records in client level. .. But My concerns related to limit that doesn't apply on map collection type. – Ratan Paul Mar 31 '16 at 13:14
  • @cropredy no map is not transient variable. I just simply tested with get set variable.. – Ratan Paul Mar 31 '16 at 13:18
  • 1
    (1) while the pagination issues raised by @crmprogdev are reasonable, if generating a CSV or Excel file, this approach could be very useful and avoid the repeats within a repeat approach workaround (of course, CSV would be unsorted) (2) a transient map would avoid viewstate issues – cropredy Mar 31 '16 at 14:58
  • @cropredy While viewstate doesn't apply when a map is declared as transient, the heap will still be limited to 6MB. – crmprogdev Mar 31 '16 at 15:15
  • @crmprogdev - yep, agree (OP mentioned Viewstate which is far more limiting than heap size) – cropredy Mar 31 '16 at 15:19
  • have you set the readonly attribute of <apex:page> tag to true? – Dnyanesh KC May 25 '16 at 10:19
  • @DnyaneshKC no. My page is not read only and my variable is not private set as well or transient. You can try yourself in any sandbox. – Ratan Paul May 25 '16 at 10:21
  • @Ratan Just curious if you saw my answer or if it is what you're actually looking for. I see that you decided the other answer didn't really address what you were looking for, but I think my own is more on topic? – Adrian Larson Aug 27 '16 at 19:08
  • @AdrianLarson you answer is the same thing that I mentioned on my question. There is no documentation why salesforce resource this allows so I am looking for answer why salesforce allows us to use map instead of list collection for more than 1K limit – Ratan Paul Aug 28 '16 at 10:57
  • 1
    It's hardly the same information. It has a concrete example and I tested it with over a million records. – Adrian Larson Aug 28 '16 at 12:02

2 Answers2

8

The original question asked how many records can be iterated, to which my answer is below.

It seems that for all practical purposes, you are only limited by Viewstate/CPU/Heap when taking this approach. Here is an extreme example where I was able to iterate a collection of one million items with no error. There is no output, and there is hardly any data. Even under these conditions, I ran out of CPU Time before running into any sort of Visualforce specific Collection Size error.

Sample Controller

public with sharing class MegaMap
{
    public Map<Integer, String> data { get; private set; }
    public MegaMap()
    {
        data = new Map<Integer, String>();
        for (Integer i = 0; i < 1000000; i++)
            data.put(i, '');
    }
}

Sample Page

<apex:page controller="MegaMap">
    <apex:repeat value="{!data}" var="i" />
</apex:page>

I ran through this demo at the end and added <apex:outputText value="{!i} /> inside the <apex:repeat> tag. Still worked.

Adrian Larson
  • 149,971
  • 38
  • 239
  • 420
0

I'm not sure how you are exactly iterating over the map, but the repeat elements in Visualforce do (should) usually not work for Maps at all.

Yes, you can keep a Map of > 1000 items in the viewstate, and the same is true for a List.

It's only starting to be a problem if you iterate over them in Visualforce using e.g. apex:repeat. Then the limit of 1000 items is enforced.

A solution/workaround to that would be to create a List<List<SObject>> listofblocks; and then iterate over them independently like this

<apex:repeat var='blockofthousand' value='{!listofblocks}'>
    <apex:repeat var='sobject' value='{!blockofthousand}'>
    ...
    </apex:repeat>
</apex:repeat>

So the outer list would e.g. have 6 entries, and then the inner lists would have 1000 items each. That way you can render > 1000 sobjects while not crossing any limits. Not tested, but should work.

Willem Mulder
  • 3,461
  • 27
  • 51
  • Willem Mulder... I think you should delete this answer. this is completely different that what i asked for. – Ratan Paul Aug 08 '16 at 13:15
  • @Ratan Well it is; you mention that you can iterate over a map with apex:repeat but that should not be possible. Is it for you? – Willem Mulder Aug 17 '16 at 18:11