10 Replies Latest reply on Oct 25, 2007 5:18 PM by pmuir

    the method invoked twice,when render the page once!

    chlol

      in my page ,only one place to inove the method,but it excuted twice,when render the page once
      i search the solution in jboss forum and google,but i cann't solve it.

      the code piece:

      <s:decorate template="layout/display.xhtml">
       <ui:define name="label">#{messages['task.principal']}</ui:define>
       <h:selectOneMenu id="userByPrincipalId" value="#{taskList.task.userByPrincipal.id}">
       <f:selectItem itemValue="-1" itemLabel="#{messages['label.selectItem.message']}"/>
       <f:selectItems value="#{userList.selectItem}"/>
       </h:selectOneMenu>
      </s:decorate>
      


      when the page render,the method getSelectItem in UserList invoked twice

      my page
      <!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
       "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
      
      <ui:composition xmlns="http://www.w3.org/1999/xhtml"
       xmlns:s="http://jboss.com/products/seam/taglib"
       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:a="https://ajax4jsf.dev.java.net/ajax"
       xmlns:rich="http://richfaces.ajax4jsf.org/rich"
       template="layout/template.xhtml">
      
       <ui:define name="body">
      
       <h:messages globalOnly="true" styleClass="message" id="globalMessages" />
      
       <h:form id="taskSearch" styleClass="edit">
      
       <rich:simpleTogglePanel
       label="#{messages['subproject']} / #{messages['task']} #{messages['label.searchCondition.title']}"
       switchType="ajax">
       <h:panelGrid columns="4" columnClass="gridContent" width="80%" algin="left">
       <s:decorate template="layout/display.xhtml">
       <ui:define name="label">#{messages['task.name']}</ui:define>
       <h:inputText id="name" value="#{taskList.task.name}"/>
       </s:decorate>
       <s:decorate template="layout/display.xhtml">
       <ui:define name="label">#{messages['task.belongProject']}</ui:define>
       <h:selectOneMenu id="projectId" value="#{taskList.task.project.id}">
       <f:selectItem itemValue="-1" itemLabel="#{messages['label.selectItem.message']}"/>
       <f:selectItems value="#{projectList.selectItemByOrdinary}"/>
       </h:selectOneMenu>
       </s:decorate>
      
      
       </h:panelGrid>
      
       <h:panelGrid columns="4" columnClass="gridContent" width="80%" algin="left">
      
       <s:decorate template="layout/display.xhtml">
       <ui:define name="label">#{messages['task.creator']}</ui:define>
       <h:selectOneMenu id="userByCreatorId" value="#{taskList.task.userByCreator.id}">
       <f:selectItem itemValue="-1" itemLabel="#{messages['label.selectItem.message']}"/>
       <f:selectItems value="#{userList.selectItem}"/>
       </h:selectOneMenu>
       </s:decorate>
      
       <s:decorate template="layout/display.xhtml">
       <ui:define name="label">#{messages['task.principal']}</ui:define>
       <h:selectOneMenu id="userByPrincipalId" value="#{taskList.task.userByPrincipal.id}">
       <f:selectItem itemValue="-1" itemLabel="#{messages['label.selectItem.message']}"/>
       <f:selectItems value="#{userList.selectItem}"/>
       </h:selectOneMenu>
       </s:decorate>
       </h:panelGrid>
      
      
       <h:panelGrid columns="4" columnClass="gridContent" width="80%" algin="left">
      
       <s:decorate template="layout/display.xhtml">
       <ui:define name="label">#{messages['task.type']}</ui:define>
       <h:selectOneMenu id="type" value="#{taskList.task.leafFlag}">
       <f:selectItem itemValue="-1" itemLabel="#{messages['label.selectItem.message']}"/>
       <f:selectItem itemValue="1" itemLabel="#{messages['subproject']}"/>
       <f:selectItem itemValue="0" itemLabel="#{messages['task']}"/>
       </h:selectOneMenu>
       </s:decorate>
      
       <s:decorate template="layout/display.xhtml">
       <ui:define name="label">#{messages['task.state']}</ui:define>
       <h:selectOneMenu id="state" value="#{taskList.task.state}">
       <f:selectItem itemValue="-1" itemLabel="#{messages['label.selectItem.message']}"/>
       <f:selectItems value="#{constants.taskState}"/>
       </h:selectOneMenu>
       </s:decorate>
       </h:panelGrid>
      
       </rich:simpleTogglePanel>
      
       <div class="actionButtons">
       <table>
       <tr>
       <td align="left">
       <h:commandButton action="/TaskList.xhtml?filter=default&proId=-2&parentId=-2"
       id="search" value="#{messages['button.search']}" />
      
       <h:commandButton
       action="/TaskList.xhtml?filter=principalisme&proId=-2&parentId=-2"
       id="principalisme"
       value="#{messages['task.principalisme']}" >
       <s:conversationPropagation type="join"/>
       </h:commandButton>
      
       <h:commandButton
       action="/TaskList.xhtml?filter=creatorisme&proId=-2&parentId=-2"
       id="creatorisme"
       value="#{messages['task.creatorisme']}" />
       <h:commandButton action="/TaskList.xhtml?filter=timeover&proId=-2&parentId=-2"
       id="timeover"
       value="#{messages['task.timeover']}"/>
       </td>
      
       <td align="right">
       <s:button view="/TaskEdit.xhtml" id="createSubproject"
       value="#{messages['button.create']}#{messages['task.onelevelsubproject']}" rendered="#{projectList.isPrincipal()}">
       <f:param name="tskId" value="0"/>
       <f:param name="taskId" />
       <f:param name="tType" value="1" />
       <s:conversationPropagation propagation="begin" />
       </s:button>
      
       <s:button view="/TaskEdit.xhtml" id="createTask"
       value="#{messages['button.create']}#{messages['task.oneleveltask']}" rendered="#{projectList.isPrincipal()}">
       <f:param name="tskId" value="0"/>
       <f:param name="taskId" />
       <f:param name="tType" value="0" />
       <s:conversationPropagation propagation="begin" />
       </s:button>
       </td>
       </tr>
       </table>
      
      
       </div>
      
      
      
      
      
       <rich:panel style="padding:0" headerClass="outpanelHeader">
      
       <h:panelGrid columns="2" columnClasses="gridContent">
       <rich:panel bodyClass="inpanelBody">
       <f:facet name="header">
       #{messages['label.tree']}
       </f:facet>
      
       <div class="sample-container">
       <rich:tree style="overflow:auto;width:288px;height:300px;" value="#{treeHome.data}" var="item" switchType="client" nodeFace="#{item.type}">
       <rich:treeNode type="library">
       <h:outputText value="#{item.type}" />
       </rich:treeNode>
       <rich:treeNode type="project">
      
       <h:outputText value="#{item.name}" />
       <a:support event="onselected" reRender="resultTable">
       <a:actionparam name="parentId" value="-1" assignTo="#{taskList.parentId}"/>
       <a:actionparam name="proId" value="#{item.id}" assignTo="#{taskList.projectId}"/>
       <a:actionparam name="order" value="beginDate asc" assignTo="#{taskList.order}"/>
       </a:support>
      
       </rich:treeNode>
       <rich:treeNode type="subproject">
       <h:outputText value="#{item.name}" />
       <a:support event="onselected" reRender="resultTable">
       <a:actionparam name="proId" value="-1" assignTo="#{taskList.projectId}"/>
       <a:actionparam name="parentId" value="#{item.id}" assignTo="#{taskList.parentId}"/>
       <a:actionparam name="order" value="beginDate asc" assignTo="#{taskList.order}"/>
       </a:support>
       </rich:treeNode>
       <rich:treeNode type="task">
       <h:outputText value="#{item.name}" />
       <a:support event="onselected" reRender="resultTable">
       <a:actionparam name="proId" value="-1" assignTo="#{taskList.projectId}"/>
       <a:actionparam name="parentId" value="#{item.id}" assignTo="#{taskList.parentId}"/>
       <a:actionparam name="order" value="beginDate asc" assignTo="#{taskList.order}"/>
       </a:support>
       </rich:treeNode>
       </rich:tree></div>
       </rich:panel>
      
       <a:outputPanel id="resultTable">
       <rich:panel bodyClass="inpanelBody" style="overflow:auto;width:600px;height:385px;">
       <f:facet name="header">#{messages['subproject']} / #{messages['task']} #{messages['label.searchResult.title']}</f:facet>
       <div class="results" id="taskList"><h:outputText
       value="#{messages['label.searchResult.null']}"
       rendered="#{empty taskList.resultList}" />
      
      
      <!-- <h:outputText value="#{taskList.parentId}" id="test"/>-->
      
      
      
      
      
       <rich:datascroller for="taskList" rendered="#{taskList.resultList.size > 10}"/>
      
       <rich:dataTable
       id="taskList" var="task" value="#{taskList.resultList}"
       rendered="#{not empty taskList.resultList}"
       rowClasses="row1,row2"
       rows="10">
       <h:column>
       <f:facet name="header">
       <s:link styleClass="columnHeader"
       value="#{messages['task.name']} #{taskList.order=='name asc' ? messages.down : ( taskList.order=='name desc' ? messages.up : '' )}">
       <f:param name="order"
       value="#{taskList.order=='name asc' ? 'name desc' : 'name asc'}" />
       </s:link>
       </f:facet>
      
      
      
      <!-- <div onclick="event.cancelBubble = true;" class="popup" id="#{task.id}" style="z-index:1000">-->
       <rich:toolTip followMouse="true" direction="top-right" delay="500" mode="client">
       <table>
       <tr>
       <td style="white-space:nowrap">#{messages['task.code']}:</td>
       <td style="white-space:nowrap">#{task.code}</td>
       </tr>
       <tr>
       <td style="white-space:nowrap">#{messages['task.type']}:</td>
       <td style="white-space:nowrap">#{task.wrappedType}</td>
       </tr>
       <tr>
       <td style="white-space:nowrap">#{messages['task.spendHour']}:</td>
       <td style="white-space:nowrap">#{task.spendHour}</td>
       </tr>
       <tr>
       <td style="white-space:nowrap">#{messages['task.createDate']}:</td>
       <td style="white-space:nowrap">
       <h:outputText value="#{task.createDate}">
       <s:convertDateTime type="both" dateStyle="long" pattern="yyyy-MM-dd"/>
       </h:outputText>
       </td>
       </tr>
       <tr>
       <td style="white-space:nowrap">#{messages['task.description']}:</td>
       <td style="white-space:nowrap">
       <h:outputText escape="false" value="#{task.wrappedDescription}"/>
       </td>
       </tr>
       <tr>
       <td colspan="2" align="left">
       <rich:separator height="1" style="padding:10px 0" />
       </td>
       </tr>
      
       <tr>
       <td style="white-space:nowrap">#{messages['task.belongProject']}:</td>
       <td style="white-space:nowrap">#{task.project.name}</td>
       </tr>
       <tr>
       <td style="white-space:nowrap">#{messages['project.creator']}:</td>
       <td style="white-space:nowrap">
       <h:outputText value="#{task.project.userByCreator.name}"/>
       </td>
       </tr>
       <tr>
       <td style="white-space:nowrap">#{messages['project.principal']}:</td>
       <td style="white-space:nowrap">
       <h:outputText value="#{task.project.userByPrincipal.name}"/>
       </td>
       </tr>
      
       </table>
       </rich:toolTip>
      
      
      
       <s:link view="/TaskEdit.xhtml"
       value="#{task.name}" id="task">
       <f:param name="taskId" value="#{task.id}" />
       <f:param name="projectId" value="#{task.project.id}" />
       <f:param name="proId" value="#{task.project.id}" />
       <f:param name="parentId" value="#{task.parentId}" />
       <f:param name="tskId" value="#{task.parentId}" />
       <f:param name="tType" value="#{task.leafFlag}" />
       </s:link>
      
       <h:outputText value="#{messages['notLeaf']}" rendered="#{task.leafFlag == 1}"/>
      
       </h:column>
      
       <h:column>
       <f:facet name="header">
       <s:link styleClass="columnHeader"
       value="#{messages['task.principal']} #{taskList.order=='principal asc' ? messages.down : ( taskList.order=='principal desc' ? messages.up : '' )}">
       <f:param name="order"
       value="#{taskList.order=='principal asc' ? 'principal desc' : 'principal asc'}" />
       </s:link>
       </f:facet>
       #{task.userByPrincipal.name}
       </h:column>
       <h:column>
       <f:facet name="header">
       <s:link styleClass="columnHeader"
       value="#{messages['task.creator']} #{taskList.order=='creator asc' ? messages.down : ( taskList.order=='creator desc' ? messages.up : '' )}">
       <f:param name="order"
       value="#{taskList.order=='creator asc' ? 'creator desc' : 'creator asc'}" />
       </s:link>
       </f:facet>
       #{task.userByCreator.name}
       </h:column>
       <h:column>
       <f:facet name="header">
       <s:link styleClass="columnHeader"
       value="#{messages['task.beginDate']} #{taskList.order=='beginDate asc' ? messages.down : ( taskList.order=='beginDate desc' ? messages.up : '' )}">
       <f:param name="order"
       value="#{taskList.order=='beginDate asc' ? 'beginDate desc' : 'beginDate asc'}" />
       </s:link>
       </f:facet>
       <h:outputText value="#{task.beginDate}">
       <s:convertDateTime type="both" dateStyle="long"
       pattern="yyyy-MM-dd" />
       </h:outputText>
      
       </h:column>
       <h:column>
       <f:facet name="header">
       <s:link styleClass="columnHeader"
       value="#{messages['task.endDate']} #{taskList.order=='endDate asc' ? messages.down : ( taskList.order=='endDate desc' ? messages.up : '' )}">
       <f:param name="order"
       value="#{taskList.order=='endDate asc' ? 'endDate desc' : 'endDate asc'}" />
       </s:link>
       </f:facet>
       <h:outputText value="#{task.endDate}">
       <s:convertDateTime type="both" dateStyle="long"
       pattern="yyyy-MM-dd" />
       </h:outputText>
      
       </h:column>
       <h:column>
       <f:facet name="header">
       <s:link styleClass="columnHeader"
       value="#{messages['task.state']} #{taskList.order=='state asc' ? messages.down : ( taskList.order=='state desc' ? messages.up : '' )}">
       <f:param name="order"
       value="#{taskList.order=='state asc' ? 'state desc' : 'state asc'}" />
       </s:link>
       </f:facet>
       #{task.wrappedState}
       </h:column>
      
       <h:column>
       <f:facet name="header">#{messages['label.header.operation']}</f:facet>
      
       <div onclick="event.cancelBubble = true;" class="popup" id="#{task.id}#{task.code}" style="z-index:1000">
       <table>
       <tr>
       <td colspan="2" align="right"><a onclick="hideCurrentPopup();return false;"><img src="img/close.png"/></a></td>
       </tr>
       <tr>
       <td colspan="2" style="white-space:nowrap">[#{task.name}]</td>
       </tr>
       <tr>
       <td colspan="2" style="white-space:nowrap">#{messages['task.operation.selectOperation']}</td>
       </tr>
       <tr>
       <td style="white-space:nowrap">
       <!-- create subproject -->
       <s:link view="/TaskEdit.xhtml"
       value="#{messages['right']}#{messages['task.operation.createSubproject']}"
       rendered="#{authenticator.user.id == task.userByPrincipal.id and task.leafFlag == 1 and task.state == 0}">
       <f:param name="proId" value="#{task.project.id}"/>
       <f:param name="tskId" value="#{task.id}"/>
       <f:param name="taskId" />
       <f:param name="tType" value="1" />
       <s:conversationPropagation propagation="begin" />
       </s:link>
       </td>
       <td style="white-space:nowrap">
       <!-- create task -->
       <s:link view="/TaskEdit.xhtml"
       value="#{messages['right']}#{messages['task.operation.createTask']}"
       rendered="#{authenticator.user.id == task.userByPrincipal.id and task.leafFlag == 1 and task.state == 0}">
       <f:param name="proId" value="#{task.project.id}"/>
       <f:param name="tskId" value="#{task.id}"/>
       <f:param name="taskId" />
       <f:param name="tType" value="0" />
       <s:conversationPropagation propagation="begin" />
       </s:link>
       </td>
       </tr>
       </table>
       </div>
       <s:link onmouseover="showPopup('#{task.id}#{task.code}', event, 'left');"
       value="#{messages['button.create']}#{messages['haveChildren']}"
       rendered="#{authenticator.user.id == task.userByPrincipal.id and task.leafFlag == 1 and task.state == 0}">
       <f:param name="taskId" value="#{task.id}" />
       </s:link>
      
       <span>      </span>
      
      
      
       <div onclick="event.cancelBubble = true;" class="popup" id="#{task.code}#{task.id}" style="z-index:1000">
       <table>
       <tr>
       <td colspan="2" align="right"><a onclick="hideCurrentPopup();return false;"><img src="img/close.png"/></a></td>
       </tr>
       <tr>
       <td colspan="2" style="white-space:nowrap">[#{task.name}]</td>
       </tr>
       <tr>
       <td colspan="2" style="white-space:nowrap">
       <h:outputText value="#{messages['task.warning.content']}" escape="false"/>
       </td>
       </tr>
       <tr>
       <td>
       <!-- close the task -->
       <s:link view="/TaskList.xhtml"
       value="#{messages['right']}#{messages['task.close']}"
       action="#{taskHome.update}"
       id="closetask"
       rendered="#{authenticator.user.id == task.userByCreator.id and task.state == 0}">
       <f:param name="id" value="#{task.id}" />
       <f:param name="tState" value="1"/>
       </s:link>
       </td>
       <td>
       <!-- cancel the task -->
       <s:link view="/TaskList.xhtml"
       action="#{taskHome.update}"
       value="#{messages['right']}#{messages['task.cancel']}"
       id="canceltask"
       rendered="#{authenticator.user.id == task.userByCreator.id and task.state == 0}">
       <f:param name="id" value="#{task.id}" />
       <f:param name="tState" value="2"/>
       </s:link>
       </td>
       </tr>
       </table>
       </div>
      
       <s:link onmouseover="showPopup('#{task.code}#{task.id}', event, 'left');"
       value="#{messages['task.changeStateOperation']}#{messages['haveChildren']}"
       rendered="#{authenticator.user.id == task.userByCreator.id and task.state == 0}">
       </s:link>
      
      
       <span>      </span>
       <s:link view="/TaskDelayEdit.xhtml"
       value="#{messages['task.operation.delay']}"
       rendered="#{authenticator.user.id == task.userByPrincipal.id and task.project.type == 1 and task.state != 1 and task.state != 2}">
       <f:param name="taskId" value="#{task.id}" />
       <f:param name="tId" value="#{task.id}" />
       <f:param name="taskDelayId"/>
       <f:param name="order" value="createDate desc"/>
       <f:param name="tType" value="#{task.leafFlag}"/>
       <s:conversationPropagation propagation="begin"/>
       </s:link>
      
       </h:column>
       </rich:dataTable>
       </div>
       </rich:panel>
       </a:outputPanel>
      
       </h:panelGrid>
       </rich:panel>
      
      </h:form>
      
       </ui:define>
      
      </ui:composition>
      


        • 1. Re: the method invoked twice,when render the page once!
          amitev

          Yes. The getters are invoked more than once per request, you should NOT put expensive logic in getter method.

          • 2. Re: the method invoked twice,when render the page once!
            chlol

            thank you,amitev!
            "The getters are invoked more than once per request",the first,i think it is not a good idea,
            the second in <f:selectItems value="#{userList.selectItem}"/> ,the expression only accept the getter method.

            and in my project,i have many getter method,in which having expensive logic.
            what can i do?
            thank you again!

            • 3. Re: the method invoked twice,when render the page once!
              chlol

              when using the non-get method,the method are invoked more than once per request!

              • 4. Re: the method invoked twice,when render the page once!
                pmuir

                Use lazy initialization e.g. @Create or @Factory. Do not put expensive logic in javabean methods

                • 5. Re: the method invoked twice,when render the page once!
                  chlol

                  i use the @Factory,but can't solve the question

                  my list bean generated jboss gen:

                  package cn.sh.guanghua.manhour.service.admin;
                  
                  import org.jboss.seam.Component;
                  import org.jboss.seam.ScopeType;
                  import org.jboss.seam.annotations.Factory;
                  import org.jboss.seam.annotations.Name;
                  import org.jboss.seam.framework.EntityQuery;
                  
                  import java.util.ArrayList;
                  import java.util.List;
                  import java.util.Arrays;
                  
                  import javax.faces.model.SelectItem;
                  import javax.persistence.Query;
                  
                  import cn.sh.guanghua.manhour.common.Constants;
                  import cn.sh.guanghua.manhour.model.admin.User;
                  import cn.sh.guanghua.manhour.service.Authenticator;
                  
                  @Name("userList")
                  public class UserList extends EntityQuery {
                  
                  
                   private long projectId = -1;
                  
                   /**
                   *
                   */
                   private static final long serialVersionUID = -4312632636363206451L;
                  
                   private static final String[] RESTRICTIONS = {
                   "lower(user.username) like concat('%',concat(lower(#{userList.user.username}),'%'))",
                   "lower(user.name) like concat('%',concat(lower(#{userList.user.name}),'%'))"};
                  
                   private User user = new User();
                  
                   @Override
                   public String getEjbql() {
                   return "select user from User user where username <> 'admin'";
                   }
                  
                   @Override
                   public Integer getMaxResults() {
                   return 15;
                   }
                  
                   public User getUser() {
                   return user;
                   }
                  
                   @Override
                   public List<String> getRestrictions() {
                   List<String> list = new ArrayList<String>();
                  
                   if (this.getUser().getState() == 0) {
                   list.add("lower(user.state) = #{userList.user.state}");
                   }
                   else if (this.getUser().getState() == 1) {
                   list.add("lower(user.state) = #{userList.user.state}");
                   }
                   else {
                   //do nothing
                   }
                   list.addAll(Arrays.asList(RESTRICTIONS));
                   return list;
                   }
                  
                   /**
                   * @return
                   */
                   @SuppressWarnings("unchecked")
                   @Factory(scope=ScopeType.CONVERSATION)
                   public List<SelectItem> getUsersByManager() {
                   Authenticator authenticator = (Authenticator) Component.getInstance("authenticator");
                   User loginUser = authenticator.getUser();
                   List<SelectItem> list = new ArrayList<SelectItem>();
                   list.add(new SelectItem(loginUser.getId(), loginUser.getName()));
                  
                   Query query = getEntityManager().createQuery("select user from User user " +
                   "where user.username <> 'admin' and user.state = 0 " +
                   " and user.userManager.id=" + loginUser.getId() + " and user.id <> " + loginUser.getId());
                   List<User> users = query.getResultList();
                   for (User user : users) {
                   list.add(new SelectItem(user.getId(), user.getName()));
                   }
                   return list;
                   }
                  
                  
                  
                  }
                  


                  my page code invoking the method:
                  <h:selectOneMenu id="principalId" value="#{activityList.principalId}" onchange="javascript:document.getElementById('weekActivity').submit();">
                   <f:selectItems value="#{userList.usersByManager}"/>
                   </h:selectOneMenu


                  • 6. Re: the method invoked twice,when render the page once!
                    chlol

                    look forward to anybody help on edge !

                    • 7. Re: the method invoked twice,when render the page once!
                      chlol

                      up

                      • 8. Re: the method invoked twice,when render the page once!
                        pmuir

                        Try

                        <h:selectOneMenu id="principalId" value="#{activityList.principalId}" onchange="javascript:document.getElementById('weekActivity').submit();">
                         <f:selectItems value="#{usersByManager}"/>
                         </h:selectOneMenu>


                        • 9. Re: the method invoked twice,when render the page once!
                          chlol

                          thank you,pete!
                          as you said,the method is invoked once,but i cann't still understand:
                          1.how the page know the method "usersByManager" in UserList?
                          2.if i have the same factory method in another class,what's the result?

                          • 10. Re: the method invoked twice,when render the page once!
                            pmuir

                            Read up on outjection in the seam reference manual.