8 Replies Latest reply on Jul 31, 2008 9:59 PM by Leo -

    entityQuery executed two times

    Leo - Newbie

      Hi!
      I am not sure if this behaviour is normal.


      I have a component that extend entityQuery. I just overrided getEjbQl method to use my own query. When debugging I noticed that the query is executed two times. There are two invocations to validate method, and two invocations to initResultList, and the sql query is written two times in the console.


      Any idea?


        • 2. Re: entityQuery executed two times
          Leo - Newbie

          Just a seam-gen sample changing ejbQl (jboss seam 2.0.1.GA)




          @Name("metodologiaList")
          public class SearchList extends EntityQuery {
          
                  private static final String[] RESTRICTIONS = {};
                  private Metodologia metodologia = new Metodologia();
          
                  @Override
                  public String getEjbql() {
                          return  "select m from Metodologia m, MetodologiaD md " +
                                          "where m=md.metodologia " +
                                          "and md.lenguaje like '"+LocaleUtil.getLocale()+"'";
          
                  }
                  @Override
                  public Integer getMaxResults() {
                          return Globals.searchListLength;
                  }
                  public Metodologia getMetodologia() {
                          return metodologia;
                  }
                  @Override
                  public List<String> getRestrictions() {
                          return Arrays.asList(RESTRICTIONS);
                  }
          
          }
          




          The .page



          <?xml version="1.0" encoding="ISO-8859-1" ?>
          <page xmlns="http://jboss.com/products/seam/pages"
                xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                xsi:schemaLocation="http://jboss.com/products/seam/pages http://jboss.com/products/seam/pages-2.0.xsd"^M
                login-required="true">
          <restrict>#{s:hasRole(globalsCNTG.adminRol)}</restrict>
             <param name="firstResult" value="#{metodologiaList.firstResult}"/>
             <param name="order" value="#{metodologiaList.order}"/>
             <param name="from"/>
          
          </page>



          And the .xhtml is just a datatable component with navigation links (next,last, first, etc)


          <ui:define name="body">
              <h:outputText value="#{messages['list.empty']}"
                         rendered="#{empty metodologiaList.resultList}"/>
          
              <rich:dataTable id="metodologiaList"
                          var="metodologia"
                        value="#{metodologiaList.resultList}"
                     rendered="#{not empty metodologiaList.resultList}">
                 
                  <h:column>
                      <f:facet name="header">
                          <s:link styleClass="columnHeader"
                                       value="#{messages['nombre']} #{metodologiaList.order=='nombre asc' ? messages.down : ( metodologiaList.order=='nombre desc' ? messages.up : '' )}">
                              <f:param name="order" value="#{metodologiaList.order=='nombre asc' ? 'nombre desc' : 'nombre asc'}"/>
                          </s:link>
                      </f:facet>
                      <h:outputText title="#{metodologia.detalles.nombre}" value="#{metodologia.detalles.nombre}"/>
                      
                  </h:column>
          ....................
          ....................
          ....................
          ....................
          
              </rich:dataTable>
          
          
              <div class="tableControl">
                  <s:link view="/metodologia/List.xhtml"
                      rendered="#{metodologiaList.previousExists}"
                         value="#{messages.left}#{messages.left} #{messages['list.firstPage']}"
                            id="firstPage">
                    <f:param name="firstResult" value="0"/>
                  </s:link>
                  <s:link view="/metodologia/List.xhtml"
                      rendered="#{metodologiaList.previousExists}"
                         value="#{messages.left} #{messages['list.previousPage']}"
                            id="previousPage">
                      <f:param name="firstResult"
                              value="#{metodologiaList.previousFirstResult}"/>
                  </s:link>
                  <s:link view="/metodologia/List.xhtml"
                      rendered="#{metodologiaList.nextExists}"
                         value="#{messages['list.nextPage']} #{messages.right}"
                            id="nextPage">
                      <f:param name="firstResult"
                              value="#{metodologiaList.nextFirstResult}"/>
                  </s:link>
                  <s:link view="/metodologia/List.xhtml"
                      rendered="#{metodologiaList.nextExists}"
                         value="#{messages['list.lastPage']} #{messages.right}#{messages.right}"
                            id="lastPage">
                      <f:param name="firstResult"
                              value="#{metodologiaList.lastFirstResult}"/>
                  </s:link>
              </div>
          
          
          </ui:define>










          • 3. Re: entityQuery executed two times
            Joseph Nusairat Newbie

            I believe you are calling it twice


                <h:outputText value="#{messages['list.empty']}"
                           rendered="#{empty metodologiaList.resultList}"/>
            
                <rich:dataTable id="metodologiaList"
                            var="metodologia"
                          value="#{metodologiaList.resultList}"
                       rendered="#{not empty metodologiaList.resultList}">
            



            The output text for saying its empty and the data table are each going to execute that query.


            • 4. Re: entityQuery executed two times
              Leo - Newbie

              I will test it later. However I think getResultList method is executed more than two times, but this doesn't cause to init query results (initResultList method) these number of times.


              My problem is that initResultList is called twice every request, not getResultList.

              • 5. Re: entityQuery executed two times
                Joseph Nusairat Newbie

                I didn't quite get that


                But initResultList is called by getResult list. And you have 3 calls to getResultList.


                public List<E> getResultList()
                   {
                      if ( isAnyParameterDirty() )
                      {
                         refresh();
                      }
                      initResultList();
                      return truncResultList(resultList);
                   }
                



                And you have about 3 calls to getResultList. Of course initResultList does check if the object (resultList) is populated first before executing another query.


                • 6. Re: entityQuery executed two times
                  Leo - Newbie

                  You are right. I confused myself. Sorry.


                  But I'm still in doubt. The method getEjbQl is called four times every request. Two from validate method ant two from initResultList


                  Moreover, my output log shows the SQL two times. Does this mean that the query is executed twice by the DBMS?

                  • 7. Re: entityQuery executed two times
                    Joseph Nusairat Newbie


                    Assuming your logger isnt responding twice then yes.


                    You know ... you're problem seems to be calling the getResultList


                    You could always set up a factory method to get the result list instead.


                    That is used in the dvdstore example


                    
                    <factory name="topProducts" 
                                 value="#{topQuery.resultList}" />
                        <framework:entity-query name="topQuery"
                                                ejbql="select p from Product p"
                                                order="p.inventory.sales desc" 
                                                max-results="8" />    
                    
                    



                    So instead you would just call topProducts and could see if that is empty instead.

                    • 8. Re: entityQuery executed two times
                      Leo - Newbie

                      Thanks Joseph!!


                      Can I use factory in getResultList method of an entityQuery component?