How to iterate over java.util.Set in JSF

Go to the new version of this blog post

I spent quite some time trying to find a solution for the following JSF issue: it is not possible to iterate over a java.util.Set.
– ui:repeat (facelets) doesn’t work
– a4j:repeat (richfaces) doesn’t work
– c:forEach works..only in case it does not rely on a variable defined by a parent component (rich:dataTable for instance)

All above are pretty logical phenomena, as UIData relies on ordered data, and generally a Set is not ordered.

In my case I had to use a Set defined in the Hibernate (JPA) object (PersistentSet).
An important note: you should use a set in case the view order is of no matter to you.

The pretty simple. And I’ll suggest it to be a part of facelets/richfaces for the next version, unless of course there is some valid specific reason for it not to be.

1. Define your own UI component extending an existing repeater component. I used a4j:repeat (HtmlAjaxRepeat)
2. Override the metohd getDataModel
3. Define your component in your faces-config
4. create a custom facelets tag definition
5. Define a context-variable in web.xml pointing to the facelet tag definition.

Note: for use with JSP instead of Facelets, you should define a .tld and a Tag handler, which is not an ojbect of this post.

Now let’s see the steps in detail:

1,2. Here some code:

package com.myproject.components;
import java.util.ArrayList;
import java.util.Set;

import javax.faces.model.DataModel;
import javax.faces.model.ListDataModel;

import org.ajax4jsf.component.html.HtmlAjaxRepeat;
import org.ajax4jsf.model.SequenceDataModel;

public class UIIterator extends HtmlAjaxRepeat {

   protected DataModel getDataModel() {
      Object current = getValue();
      if(current instanceof Set){
          return new SequenceDataModel(new ListDataModel(
                new ArrayList((Set) current)));
      return super.getDataModel();

So, as we don’t care about the order of the elements, we just create a new ArrayList out of the Set. And we can now easily return the appropirate DataModel.

3. Add this to your faces-config. (I copied it from the a4j definition)

		<description />


4. Here is the tag definition for facelets

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE facelet-taglib PUBLIC
"-//Sun Microsystems, Inc.//DTD Facelet Taglib 1.0//EN"
<facelet-taglib xmlns="">



Save this file as /WEB-INF/facelets/custom.taglib.xml

5. Add to your web.xml


6. It is now ready to use


<cust:repeat var=”myVar” value=”${aSet}”>


I think it is way neater than other workarounds, like defining a custom EL Resolver.


14 Responses to “How to iterate over java.util.Set in JSF”

  1. How to Get Six Pack Fast Says:

    This is very hot info. I’ll share it on Twitter.

  2. Liza Says:

    After reading the article, I feel that I need more information on the topic. Can you suggest some resources please?

  3. Sandro Mancuso Says:

    Thanks Bozho. It works perfectly. I’ll also share it on Twitter.

  4. Berd Says:

    I tried your approach, but I do not get the values rendered inside the new component. Any idea?

  5. Bozho Says:

    No, at least until provide more data on the exact issue 😉

    • Berd Says:


      yes sorry but my code snippet was not posted:

      I implemented exactly the same you did here. No I integrated this into a JSF page and I have the following:

      I have a user bean containing several roles (this is the set) and I use rich:dataList for iterating over the users. Now inside the rich:datalist I use the cust:repeat using the roles attribute as value. Now I am using a h:outputText for printing out the var: myVar and I do not get any data on the screen. But the data is inside the loaded object.

      • Bozho Says:

        If you want to use the iteration on rich:dataList, you must extend HtmlDataList instead of HtmlAjaxRepeat

  6. Flávio Says:

    There’s an easier way.

  7. Flávio Says:

    (the code wasn’t send)
    There’s an easier way.
    c:forEach var=”element_” items=”#{anyObject.elements}”
    c:set var=”element” value=”#{element_}” scope=”request”/
    h:outputText value=”#{element.description} “/

    • Rose Says:

      – avoid problems: do not use jstl in jsf
      – the custom tag proposed by bozhobg works great 🙂 many thanks

  8. jkubec Says:

    Hello, it’s nice…but I got this mistake:
    19:06:32,223 ERROR [viewhandler] Error Rendering View[/pages/access/list.xhtml]
    java.lang.IllegalArgumentException: Component form_access:tab_one:0:j_id70 not instance of org.ajax4jsf.component.UIRepeat

    Could you help me this fix?


  9. 在JSF和SEAM中对java.util.Set及其子类作循环 « Sealyu's Blog Says:

    […] Here some code: view plaincopy to […]

  10. László van den Hoek Says:

    Your tag handler code could be made more generic to accept not only Set, but all of Collection (I also added a type so you can drop the @SuppressWarnings annotation):


    protected DataModel getDataModel() {
    Object current = getValue();
    if (current instanceof Collection && !(current instanceof List)) {
    return new SequenceDataModel(
    new ListDataModel(
    new ArrayList(
    (Collection) current
    return super.getDataModel();


  11. László van den Hoek Says:

    hmm, the type got scrubbed (should be “Object” for the ArrayList and “?” for the Collection) and the indentation was removed – but the code is still valid without those 🙂

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s

%d bloggers like this: