6 Replies Latest reply on Jul 7, 2007 8:42 PM by alexg79

    <s:cache> and nested repeat elements

    alexg79

      I need to display a nested list as follows:

      Root category 1
       Subcategory 1
       Subcategory 2
      Root category 2
       Subcategory 3

      I first tried doing this using the Facelets <ui:repeat> element, only to find out that only the outer layer (the root categories) were rendered. Using JSTL's <c:forEach> fixed this, but caching no longer works as intended, since I'm getting database hits on every pageload. I have a similar page elsewhere that uses <ui:repeat> instead, and caching works fine there. This is quite annoying since constructing said list is fairly database intensive and the data rarely changes.
      Any advice?


        • 1. Re: <s:cache> and nested repeat elements
          gavin.king

          I guess that the JSTL tag probably works better in JSF 1.2, have you tried that?

          But I dont understand why ui:repeat would not work...?

          • 2. Re: <s:cache> and nested repeat elements
            alexg79

            I'm using JBoss 4.2.0GA and therefore JSF 1.2, with Seam 2.0.0beta1. Perhaps this is a Facelets issue?
            Here's the xhtml snippet:

             <s:cache key="mainPage" region="/pageFragments">
             <tr class="headercell">
             <td class="category">Category</td>
             <td class="files">Files</td>
             <td class="lastentry">Last Entry</td>
             </tr>
             <c:forEach items="#{categories}" var="root">
             <tr class="bodycellheader">
             <td class="category">
             <div class="arrow">»</div>
             <div class="catname">
             <s:link view="/category.xhtml" value="#{root.name}">
             <f:param name="categoryId" value="#{root.id}"/>
             </s:link>
             </div>
             </td>
             <td class="files">#{root.numEntries}</td>
             <td class="lastentry">
             <s:link view="/entry.xhtml" value="#{root.lastEntry.title}">
             <f:param name="entryId" value="#{root.lastEntry.id}"/>
             </s:link>
             </td>
             </tr>
             <c:forEach items="#{root.subcategories}" var="cat">
             <tr class="bodycellsubheader">
             <td style="padding-left: 2.4em;" class="category">
             <s:link view="/cat.xhtml" value="#{cat.name}">
             <f:param name="categoryId" value="#{cat.id}"/>
             </s:link><br />
             <div class="catdesc">#{cat.description}</div>
             </td>
             <td class="files">#{cat.numEntries}</td>
             <td class="lastentry">
             <s:link view="/entry.xhtml" value="#{cat.lastEntry.title}">
             <f:param name="categoryId" value="#{cat.lastEntry.id}"/>
             </s:link>
             </td>
             </tr>
             </c:forEach>
             </c:forEach>
             <tr class="bodycellheader">
             <td class="category">
             <div class="arrow">»</div>
             <div class="catname"><s:link view="/viewall.xhtml">View
             All Files</s:link><br />
             View all of the files in the database</div>
             </td>
             <td class="files">#{home.totalEntryCount}</td>
             <td class="lastentry">
             <s:link view="/entry.xhtml" value="#{home.lastEntryTitle}">
             <f:param name="entryId" value="#{home.lastEntryId}"/>
             </s:link>
             </td>
             </tr>
             </s:cache>
            

            and the backing bean:
            @Scope(ScopeType.EVENT)
            @Name("home")
            @Stateful
            public class HomeBean implements HomeLocal {
            
             @PersistenceContext(type = PersistenceContextType.EXTENDED)
             private EntityManager em;
            
             private int totalEntryCount;
             private Long lastEntryId;
             private String lastEntryTitle;
            
             @SuppressWarnings("unchecked")
             @Factory("categories")
             public List<Category> initCategories() {
             List<Category> categories = em.createNamedQuery(Category.QUERY_ROOTCATEGORIES).getResultList();
             for (Category cat : categories) {
             totalEntryCount += cat.getEntries().size();
             Entry lastEntry = cat.getEntries().get(0);
             if (lastEntry != null && (lastEntryId == null || lastEntry.getId() > lastEntryId)) {
             lastEntryId = lastEntry.getId();
             lastEntryTitle = lastEntry.getTitle();
             }
             }
             return categories;
             }
            
             public int getTotalEntryCount() {
             return totalEntryCount;
             }
            
             public Long getLastEntryId() {
             return lastEntryId;
             }
            
             public String getLastEntryTitle() {
             return lastEntryTitle;
             }
            
             @Remove @Destroy
             public void destroy() {}
            
            }


            • 3. Re: <s:cache> and nested repeat elements
              alexg79

              I found this:
              http://wiki.java.net/bin/view/Projects/FaceletsFAQ#Why_doesn_t_my_c_if_ui_repeat_ui
              and this:
              http://www.ninthavenue.com.au/blog/c:foreach-vs-ui:repeat-in-facelets
              but I'm still confused. How should I go about with this? Forcibly try to cram this into a <h:dataTable>?

              • 4. Re: <s:cache> and nested repeat elements
                gavin.king

                Try the facelets mailing list.

                • 5. Re: <s:cache> and nested repeat elements
                  alexg79

                  On a closer inspection, the <s:cache> tag does seem to help considerably. Although I still get database hits on page load, only a few queries are executed each time and the loading time is about 1/7 of normal.
                  Maybe some fine day I'll understand all this :P

                  • 6. Re: <s:cache> and nested repeat elements
                    alexg79

                    Alright... *sigh* false alarm. Seems like there was a mixup between the "items" and "value" parameters between the <c:forEach> and <ui:repeat> elements, that's all. Even when I knew they had different parameters for that...