0

I have test.xhtml with:

<h:form id="formProduct" >
  <h:panelGroup id="filterProductTotal" layout="block">
    <h:outputText value="#{filtersControllerRequestScoped.filteredProductsCount}"/>                            
  </h:panelGroup>
  <div id="product_container">
    <ui:repeat value="#{filtersControllerRequestScoped.getFilteredProducts(1)}" var="product">  
      <div class="item">
        <util:product-item-preview_2 productItem="#{product}"/>
      </div>
    </ui:repeat>                
  </div>
</h:form>    

I read about the problem of repeated call methods, and fought to keep the business logic of the GET methods and tried to realize LAZY load.

Method getFilteredProducts() in request scoped bean called in various requests, even when I don't update form id="formProduct". Requests called by "p:ajax" or "p:remoteCommand" with and without "update" anithig.

Problem for me - I don't understand why the method "getFilteredProducts" is called each time (every ajax call), but "filteredProductsCount" only once when the page is loaded.

Update: some idea.

May be when i use "#{product}" in other requests in fact i use "#{filtersControllerRequestScoped.getFilteredProducts(1).get(INDEX)}", not an simple object "#{product}"?

Update: Part of <util:product-item-preview_2/>:

<composite:interface name="productItemPreview" displayName="hello">
    <composite:attribute name="productItem"/>
</composite:interface>

<composite:implementation>
...
  <h:commandLink value="quick order" onclick="quickOrderPrepare(#{cc.attrs.productItem.productId})">
    <p:ajax process="@this" oncomplete="quickOrderShow()" partialSubmit="true"/>
  </h:commandLink>
...
  <span class="b-prices">
    <h:outputText value="Price: "/>
    <h:outputText value="#{discountControllerRequestScoped.getProductPrice(cc.attrs.productItem)}">
      <f:convertNumber minFractionDigits="2" maxFractionDigits="2"/>
    </h:outputText>
  </span>

...

<script>
function quickOrderPrepare(productId) {
  setProductQuickOrderPanelRemoteCommand([{name: 'productId', value: productId}]);
}            
function quickOrderShow(){
  updateQuickOrderPanelRemoteCommand();
  $('.popup.productQuickOrder').bPopup({            
    onClose: function() { updateBasket(); }
  });                
}
</script>

setProductQuickOrderPanelRemoteCommand and updateQuickOrderPanelRemoteCommand are primefaces remotecommand.

andrey.ladniy
  • 1,664
  • 1
  • 11
  • 27
  • [Just stop doing business logic in getters](http://stackoverflow.com/questions/2090033/why-jsf-calls-getters-multiple-times/2090062#2090062). – BalusC Apr 08 '13 at 15:15
  • do you mean not to make queries to the database and store the data in an list of `@ViewScoped` bean on init? I did so in the first place, but when thought that these data are needed only once redid by `@RequestScoped + Stateless`. Сan you explain why the method `getFilteredProductsCount` is called once, and the `getFilteredProducts` several times (both in one bean). I tried `` and `getFilteredProduct` called ones in RENDER_RESPONSE phase – andrey.ladniy Apr 08 '13 at 15:54

1 Answers1

0

Based on BalusC's blog, in my understanding, when you use #{product} in some requests, the whole view will first be restored. Since your bean is @RequestScoped, there's nothing left of your filteredProducts list from the previous request. Even if you change your scope to @ViewScoped, you may still have the same problem because you didn't store the filteredProducts as a property of the bean. As a consequence, JSF cannot know what product was submitted. Hence, your list will be rebuilt.

I think you should change your bean to @ViewScoped and store your filteredProducts as a property of the bean. Don't use getFilteredProducts(1) to get the list out.

Mr.J4mes
  • 9,168
  • 9
  • 48
  • 90
  • I don't want change to `@ViewScoped` and store all lists of `filteredProducts` for every view (session), because it used once when render page and while there is no changes of filter. But if i leave `@RequestScoped` the method will be called (calling DB query) multiple times... Are there any other ways to work around this problem (exept `@ViewScoped`)? – andrey.ladniy Apr 08 '13 at 11:33
  • I'm not really sure if there's another way. Can you provide the snippet where you use `#{product}` in some requests? – Mr.J4mes Apr 08 '13 at 12:09
  • i update first post and add some code where i'm using `#{product}` . Method `getFilteredProducts` calling on all and (there is no using `#{product}` – andrey.ladniy Apr 08 '13 at 13:36
  • i tried change `ui:repeat` on `h:dataTable` and have no calling `getFilteredProducts` on RENDER_RESPONSE phase. All fine, but in result i have HTML table... – andrey.ladniy Apr 08 '13 at 14:05