8 Replies Latest reply on Aug 21, 2009 6:19 PM by hardaur

    EntityQuery Performance, just don't get it

    hardaur

      I'm working on doing some light performance tuning of a Seam 2.1.1 app that makes heavy use of EntityQuery objects.  The primary problem I have is the extremely repetitive queries being run when a page is loaded do to JSF and getters.  So I'm trying to find ways of getting around that and have been googling for a couple days.  It seems as though there are two ways around it based on what I've found:  bypassing interceptors or using a factory method.  I've chosen the later and it does avoid the queries, however. . there is one MAJOR problem.  There are a few ways to explain it (it's the same with all filtering), but let's use paging.


      1.  I load the page (page 1) everything's groovy.
      2.  I use EntityQuery.next() to go to page 2 - It still shows page 1
      3.  I use EntityQuery.next() to go to page 3 - It now shows page 2
      4.  I use EntityQuery.next() to go to page 4   It now shows page 3


      Same for filtering:  If I load page all are shown, if I filter for x (via restrictions) it still shows all, if I filter for y, it'll show the x filters applied.


      Here's the relevant code (I think):


      From the xhtml:


      
                                              <ice:dataTable id="entityListDataTableId"
                                                      var="myEntity"
                                                      value="#{customResultList}"
                                                      rendered="#{not empty customResultList}"
                                                      width="100%">
      



      From the EntityQuery object:


      @Factory(value = "customResultList", scope = ScopeType.EVENT)
              public List customResultListInitializer()
              {
                      return  getResultList();
              }
      



      I'm using icefaces, so using ScopeType.EVENT as a PAGE is very rare.  Like I said, in general everything is working fine, just have a  sync issue.


      So, I'm feeling pretty stupid, after tons and TONS of googling I've found very little.  Am I the only one out there that's missing out on some big secret on how to do this? : b  Am I doing something slightly wrong?  Is there another way entirely that I'm missing out on?


      Thanks for any and all assistance!


      Gerald

        • 1. Re: EntityQuery Performance, just don't get it
          jguglielmin

          You don't specify if you are using the


          <ice:dataPaginator>



          component, or are using the pagination attributes of EntityQuery.  If it's the latter, you can just use seam-gen and see how that is done.  If you want examples of the former, please request what you are looking for on the ICEfaces forum

          • 2. Re: EntityQuery Performance, just don't get it
            hardaur

            I'm not using the ice paginator stuff.  Just the standard seam stuff.  Here's my pager.xhtml facelet:


            <ui:composition xmlns="http://www.w3.org/1999/xhtml"
                xmlns:ui="http://java.sun.com/jsf/facelets"
                xmlns:f="http://java.sun.com/jsf/core"
                xmlns:h="http://java.sun.com/jsf/html"
                xmlns:c="http://java.sun.com/jstl/core"
                xmlns:ice="http://www.icesoft.com/icefaces/component"
                xmlns:s="http://jboss.com/products/seam/taglib">
                
                
                
                <ice:form>
                      <table id="pagerTable" cellspacing="0" cellpadding="0">
                           <tr>
                                <td align="center">
                                     <h:commandLink
                                          action="#{entityList.first}"
                                    disabled="#{not entityList.previousExists}"
                                    onclick="blur(); top.scroll(0,0);">
                                          <ice:graphicImage url="#{entityList.previousExists ? '/images/pager_first_en.png' : '/images/pager_first_dis.png'}" style="border:none;"/>
                                     </h:commandLink>
                                </td>
                                <td align="center">
                                     <h:commandLink
                                          action="#{entityList.previous}"
                                    disabled="#{not entityList.previousExists}"
                                    onclick="blur(); top.scroll(0,0);">
                                          <ice:graphicImage url="#{entityList.previousExists ? '/images/pager_prev_en.png' : '/images/pager_prev_dis.png'}" style="border:none;" />
                                     </h:commandLink>
                                </td>
                            <td align="center">
                                <ice:selectOneMenu
                                    value="#{entityList.currentPage}"
                                    partialSubmit="true">
                                   
                                   <s:selectItems value="#{entityList.pageList}"
                                   var="page"
                                   label="#{page}"/>
                                    
                                </ice:selectOneMenu> / #{entityList.pageCount}
                            </td>
                                <td align="center">
                                     <h:commandLink
                                          action="#{entityList.next}"
                                    disabled="#{not entityList.nextExists and entityList.currentPage ge entityList.pageCount}"
                                    onclick="blur(); top.scroll(0,0);">
                                          <ice:graphicImage url="#{entityList.nextExists or entityList.currentPage lt entityList.pageCount ? '/images/pager_next_en.png' : '/images/pager_next_dis.png'}" style="border:none;" />
                                     </h:commandLink>
                                </td>
                                <td align="center">                         
                                     <h:commandLink
                                          action="#{entityList.last}"
                                    disabled="#{not entityList.nextExists and entityList.currentPage ge entityList.pageCount}"
                                    onclick="blur(); top.scroll(0,0);">
                                          <ice:graphicImage url="#{entityList.nextExists or entityList.currentPage lt entityList.pageCount ? '/images/pager_last_en.png' : '/images/pager_last_dis.png'}" style="border:none;" />
                                     </h:commandLink>
                                </td>
                           </tr>
                           <tr>
                                <td align="center" style="font-size: .75em;">
                                     First
                                </td>
                                <td align="center" style="font-size: .75em;">
                                     Prev.
                                </td>
                            <td align="center" style="font-size: .75em;">
                                Go to Page (#{entityList.currentPage})
                            </td>
                                <td align="center" style="font-size: .75em;">
                                     Next
                                </td>
                                <td align="center" style="font-size: .75em;">
                                     Last
                                </td>
                           </tr>
                      </table>
                 </ice:form>
                
            </ui:composition>
            
            
            



            But again, it's not just paging.  Sorting, filtering (changing restrictions), etc.  Same behavior.


            Thanks!


            Gerald

            • 3. Re: EntityQuery Performance, just don't get it
              jguglielmin

              You might want to generate some pages using seam-gen with the ICEFaces option.  Not sure what your onclick javascript function is doing.  Generally when using the entity query, you use it with some page parameters and an s link component.  (again see the standard seam-gen generated templates).  Did you try and hit page refresh (on the browser) after you click on the commandLink?  You could try using the setEventPhase component if the refresh gives you the required results in your view.  This is just the quirks of the jsf lifecycle and when things are updated.

              • 4. Re: EntityQuery Performance, just don't get it
                hardaur

                judy guglielmin wrote on Aug 20, 2009 18:22:


                You might want to generate some pages using seam-gen with the ICEFaces option.  Not sure what your onclick javascript function is doing.  Generally when using the entity query, you use it with some page parameters and an s link component.  (again see the standard seam-gen generated templates).  Did you try and hit page refresh (on the browser) after you click on the commandLink?  You could try using the setEventPhase component if the refresh gives you the required results in your view.  This is just the quirks of the jsf lifecycle and when things are updated.


                Using icefaces the page doesn't update, just pieces of it.  That being the case I have to manually scroll the window back to the top.  That's what the onclick stuff does, so shouldn't be relevant.


                I honestly don't think this has anything to do with icefaces at all. It's the JSF lifecycle and the EntityQuery.  My best guess at this point is that I'm getting caught up in a new JSF request lifecycle issue where the @Factory method is firing before the query is able to update.  That explains why the Factories object is always one request behind.


                Anybody?


                Thanks!


                Gerald

                • 5. Re: EntityQuery Performance, just don't get it
                  hardaur

                  I've pretty much confirmed that the object being created by the Factory is being instantiated BEFORE the request parameters are being processed making them seem a request behind. 


                  So when I start, for instance


                  1.  firstResult == null
                  2.  page renders fine
                  3.  Click next (to go to page 2)
                  4. firstResult == null (should be 10)
                  5.  Click next (go to page 3)
                  6. firstResult == 10 (should be 20)
                  7. Click First to go back to page 1
                  8. firstResult == 20 (should be 0)
                  



                  etc


                  Does anybody have a different way to handle this or to adjust when the factory fires?


                  Gerald

                  • 6. Re: EntityQuery Performance, just don't get it
                    kukeltje.ronald.jbpm.org

                    Gerald,


                    Have you already tried what Judy suggested:



                    You might want to generate some pages using seam-gen with the ICEFaces option

                    And find the important 'differences' with your project.

                    • 7. Re: EntityQuery Performance, just don't get it
                      brandonsimpson

                      I may be wrong on this, but I think the problem is probably the EVENT scope on your @Factory method. If I recall correctly, there is something wierd with the standard JSF event scope being created before the Seam scopes, so that's probably causing your result list to be using values that are one page behind. The reason it probably works the first time is that the view is not restored. I would change the scope and find some other way to do what you are trying to do if you are not getting the result you want.

                      • 8. Re: EntityQuery Performance, just don't get it
                        hardaur

                        Brandon,


                          Pretty sure you just hit the nail on the head. That would make sense for exactly what I'm seeing.   I'd already backed out the factory stuff and went a different direction that's working well (though a little more tedious, doing dirty flags).


                        Thanks!


                        Gerald