Konstruktor bean CDI i @PostConstruct nazywano wiele razy

Po kilku eksperymentach wydaje się, że jest to problem podczas używania fasoli CDI i nic wspólnego z PrimeFaces, co pierwotnie zakładałem.

Jeśli zmienię TableBeanLazy na Managed Bean przy użyciu @ManagedBean, wtedy konstruktor i metoda @PostConstruct zostaną wywołane tylko raz, jak oczekiwałem.

Czy ktoś może rzucić jakieś światło na ten temat?

================================================== =

Jestem całkiem nowy w JSF i PrimeFaces, więc wszelkie wskazówki będą bardzo mile widziane. Szukałem innych wpisów i przeczytałem kilka podobnych, ale nie mogę znaleźć rozwiązania.

Próbuję uzyskać przykład tabeli Lazy Loading Data w witrynie PrimeFaces Showcase działającej w moim projekcie, ale mam problemy z powodu braku zachowania klasy bean tak, jak oczekiwałem.

Wprowadziłem kilka zmian do przykładowego kodu z witryny PrimeFaces: - zmieniono nazwę klasy TableBean na TableBeanLazy; dodano adnotacje do klasy; przydzielone statyczne tablice ciągów; przeniesiono inicjalizację z konstruktora do metody @PostConstruct initialise (); przydzielonosamochody zmienna składowa.

Dodałem też do konstruktora komunikaty śledzenia i metodę @PostConstruct, które pokazują, że oba są wywoływane wielokrotnie, gdy tabela jest wyświetlana po raz pierwszy, wiele razy za każdym kliknięciem ikony wyszukiwania i wiele razy przy każdym wpisaniu znaku w pole filtru.

Powoduje to, że losowa lista obiektów samochodów jest odtwarzana za każdym razem, gdy podejmowana jest akcja, więc sortowanie i filtrowanie nigdy nie przyniesie oczekiwanych rezultatów - co robią podczas uruchamiania przykładu bezpośrednio na stronie PrimeFaces Showcase.

Chociaż początkowo korzystałem z @ViewScoped, próbowałem także @RequestScoped i wreszcie @SessionScoped, ale wszystkie zachowują się w ten sam sposób.

Czy wielokrotne wywołania konstruktora i @PostConstruct oczekiwane zachowanie dla komponentu bean?

Jeśli tak, w jaki sposób działa kod przykładowy podany na stronie PrimeFaces Showcase?

Jak to rozwiązać?

Środowisko

PrimeFaces 3.5
JSF 2.1
JDK 1.7
GlassFish Server Open Source Edition 3.1.2.2 (build 5)
Mojarra 2.1.6 (SNAPSHOT 20111206)
Netbeans IDE 7.3
Windows 7 Pro x64

MyTable.xhtml

<?xml version='1.0' encoding='UTF-8' ?>
<!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:ui="http://java.sun.com/jsf/facelets"
  template="./resources/templates/platform_tpl.xhtml"
  xmlns:p="http://primefaces.org/ui"
  xmlns:h="http://java.sun.com/jsf/html"
  xmlns:f="http://java.sun.com/jsf/core">

  <ui:define name="body">
    <h2 style="margin-top: 0px; padding-top: 0px;">Cars List</h2>

    <h:form id="form">
      <p:dataTable var="car" value="#{tableBeanLazy.lazyModel}" paginator="true" rows="10"
        paginatorTemplate="{RowsPerPageDropdown} {FirstPageLink} {PreviousPageLink} {CurrentPageReport} {NextPageLink} {LastPageLink}"
        rowsPerPageTemplate="5,10,15" selectionMode="single" selection="#{tableBeanLazy.selectedCar}" id="carTable" lazy="true">

      <p:column headerText="Model" sortBy="#{car.model}" filterBy="#{car.model}">
        <h:outputText value="#{car.model}" />
      </p:column>

      <p:column headerText="Year" sortBy="#{car.year}" filterBy="#{car.year}">
        <h:outputText value="#{car.year}" />
      </p:column>

      <p:column headerText="Manufacturer" sortBy="#{car.manufacturer}" filterBy="#{car.manufacturer}">
        <h:outputText value="#{car.manufacturer}" />
      </p:column>

      <p:column headerText="Color" sortBy="#{car.color}" filterBy="#{car.color}">
        <h:outputText value="#{car.color}" />
      </p:column>
      </p:dataTable>
    </h:form> 
  </ui:define>
</ui:composition>

TableBeanLazy.java

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package BackEnd;

import java.util.ArrayList;
import java.util.List;  
import javax.annotation.PostConstruct;
import javax.faces.bean.SessionScoped;
import javax.inject.Named;

import org.primefaces.model.LazyDataModel;  

@Named(value = "tableBeanLazy")
@SessionScoped
public class TableBeanLazy
{
  static String[] colors = new String[10];
  static String[] manufacturers = new String[10];
  static String[] models = new String[5];

  private LazyDataModel<Car> lazyModel;  

  private Car selectedCar;  

  private List<Car> cars;  

  static
  {
    colors[0] = "Black";  
    colors[1] = "White";  
    colors[2] = "Green";  
    colors[3] = "Red";  
    colors[4] = "Blue";  
    colors[5] = "Orange";  
    colors[6] = "Silver";  
    colors[7] = "Yellow";  
    colors[8] = "Brown";  
    colors[9] = "Maroon";  

    manufacturers[0] = "Mercedes";  
    manufacturers[1] = "BMW";  
    manufacturers[2] = "Volvo";  
    manufacturers[3] = "Audi";  
    manufacturers[4] = "Renault";  
    manufacturers[5] = "Opel";  
    manufacturers[6] = "Volkswagen";  
    manufacturers[7] = "Chrysler";  
    manufacturers[8] = "Ferrari";  
    manufacturers[9] = "Ford";

    models[0] = "Sports";
    models[1] = "Saloon";
    models[2] = "SUV";
    models[3] = "Hybrid";
    models[4] = "Estate";
  }  

  public TableBeanLazy()
  {
    System.out.println("-->  In constructor for TableBeanLazy");
  }

  @PostConstruct
  public void initialise()
  {
    System.out.println("-->  In initialise for TableBeanLazy");

    cars = new ArrayList<Car>();

    populateRandomCars(cars, 5);

    lazyModel = new LazyCarDataModel(cars);  
  }

  public Car getSelectedCar()
  {
    return selectedCar;
  }  

  public void setSelectedCar(Car selectedCar)
  {
    this.selectedCar = selectedCar;
  }

  public LazyDataModel<Car> getLazyModel()
  {
    return lazyModel;
  }

  private void populateRandomCars(List<Car> list, int size)
  {
    System.out.println("-->  In populateRandomCars for TableBeanLazy");

    for(int i = 0 ; i < size ; i++)
    {
      list.add(new Car(getRandomModel(), getRandomYear(), getRandomManufacturer(), getRandomColor()));  
    }  
  }  

  private String getRandomColor()
  {
    return colors[(int)(Math.random() * 10)];
  }

  private String getRandomManufacturer()
  {
    return manufacturers[(int) (Math.random() * 10)];
  }

  private String getRandomModel()
  {
    return models[(int)(Math.random() * 5)];
  }

  private int getRandomYear()
  {
    return (int)(Math.random() * 50 + 1960);
  }
}

Wyjście przy początkowym wyświetlaniu tabeli

INFO: -->  In constructor for TableBeanLazy
INFO: -->  In initialise for TableBeanLazy
INFO: -->  In populateRandomCars for TableBeanLazy
INFO: -->  In constructor for TableBeanLazy
INFO: -->  In initialise for TableBeanLazy
INFO: -->  In populateRandomCars for TableBeanLazy
INFO: -->  In constructor for TableBeanLazy
INFO: -->  In initialise for TableBeanLazy
INFO: -->  In populateRandomCars for TableBeanLazy

Wyjście po kliknięciu ikony wyszukiwania

INFO: -->  In constructor for TableBeanLazy
INFO: -->  In initialise for TableBeanLazy
INFO: -->  In populateRandomCars for TableBeanLazy
INFO: -->  In constructor for TableBeanLazy
INFO: -->  In initialise for TableBeanLazy
INFO: -->  In populateRandomCars for TableBeanLazy
INFO: -->  In constructor for TableBeanLazy
INFO: -->  In initialise for TableBeanLazy
INFO: -->  In populateRandomCars for TableBeanLazy
INFO: -->  In constructor for TableBeanLazy
INFO: -->  In initialise for TableBeanLazy
INFO: -->  In populateRandomCars for TableBeanLazy
INFO: java.lang.ArithmeticException: / by zero
java.lang.ArithmeticException: / by zero
  at org.primefaces.model.LazyDataModel.setRowIndex(LazyDataModel.java:62)
  at org.primefaces.component.api.UIData.setRowModel(UIData.java:409)
  at org.primefaces.component.api.UIData.setRowIndex(UIData.java:401)
  at org.primefaces.component.api.UIData.processChildren(UIData.java:289)
  at org.primefaces.component.api.UIData.processPhase(UIData.java:261)
  at org.primefaces.component.api.UIData.processDecodes(UIData.java:227)
  at com.sun.faces.context.PartialViewContextImpl$PhaseAwareVisitCallback.visit(PartialViewContextImpl.java:506)
  at com.sun.faces.component.visit.PartialVisitContext.invokeVisitCallback(PartialVisitContext.java:183)
  at org.primefaces.component.api.UIData.visitTree(UIData.java:639)
  at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
  at javax.faces.component.UIForm.visitTree(UIForm.java:344)
  at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
  at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
  at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
  at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
  at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
  at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
  at com.sun.faces.context.PartialViewContextImpl.processComponents(PartialViewContextImpl.java:376)
  at com.sun.faces.context.PartialViewContextImpl.processPartial(PartialViewContextImpl.java:252)
  at javax.faces.context.PartialViewContextWrapper.processPartial(PartialViewContextWrapper.java:183)
  at javax.faces.component.UIViewRoot.processDecodes(UIViewRoot.java:931)
  at com.sun.faces.lifecycle.ApplyRequestValuesPhase.execute(ApplyRequestValuesPhase.java:78)
  at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
  at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
  at javax.faces.webapp.FacesServlet.service(FacesServlet.java:593)
  at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1550)
  at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:281)
  at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
  at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:655)
  at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595)
  at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:161)
  at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:331)
  at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:231)
  at com.sun.enterprise.v3.services.impl.ContainerMapper$AdapterCallable.call(ContainerMapper.java:317)
  at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:195)
  at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:860)
  at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:757)
  at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1056)
  at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:229)
  at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137)
  at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104)
  at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)
  at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79)
  at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54)
  at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)
  at com.sun.grizzly.ContextTask.run(ContextTask.java:71)
  at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532)
  at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513)
  at java.lang.Thread.run(Thread.java:722)

INFO: -->  In constructor for TableBeanLazy
INFO: -->  In initialise for TableBeanLazy
INFO: -->  In populateRandomCars for TableBeanLazy
INFO: -->  In constructor for TableBeanLazy
INFO: -->  In initialise for TableBeanLazy
INFO: -->  In populateRandomCars for TableBeanLazy
INFO: -->  In constructor for TableBeanLazy
INFO: -->  In initialise for TableBeanLazy
INFO: -->  In populateRandomCars for TableBeanLazy
INFO: java.lang.ArithmeticException: / by zero
java.lang.ArithmeticException: / by zero
  at org.primefaces.model.LazyDataModel.setRowIndex(LazyDataModel.java:62)
  at org.primefaces.component.api.UIData.setRowModel(UIData.java:409)
  at org.primefaces.component.api.UIData.setRowIndex(UIData.java:401)
  at org.primefaces.component.api.UIData.processChildren(UIData.java:289)
  at org.primefaces.component.api.UIData.processPhase(UIData.java:261)
  at org.primefaces.component.api.UIData.processValidators(UIData.java:241)
  at com.sun.faces.context.PartialViewContextImpl$PhaseAwareVisitCallback.visit(PartialViewContextImpl.java:508)
  at com.sun.faces.component.visit.PartialVisitContext.invokeVisitCallback(PartialVisitContext.java:183)
  at org.primefaces.component.api.UIData.visitTree(UIData.java:639)
  at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
  at javax.faces.component.UIForm.visitTree(UIForm.java:344)
  at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
  at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
  at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
  at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
  at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
  at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
  at com.sun.faces.context.PartialViewContextImpl.processComponents(PartialViewContextImpl.java:376)
  at com.sun.faces.context.PartialViewContextImpl.processPartial(PartialViewContextImpl.java:252)
  at javax.faces.context.PartialViewContextWrapper.processPartial(PartialViewContextWrapper.java:183)
  at javax.faces.component.UIViewRoot.processValidators(UIViewRoot.java:1170)
  at com.sun.faces.lifecycle.ProcessValidationsPhase.execute(ProcessValidationsPhase.java:76)
  at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
  at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
  at javax.faces.webapp.FacesServlet.service(FacesServlet.java:593)
  at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1550)
  at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:281)
  at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
  at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:655)
  at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595)
  at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:161)
  at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:331)
  at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:231)
  at com.sun.enterprise.v3.services.impl.ContainerMapper$AdapterCallable.call(ContainerMapper.java:317)
  at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:195)
  at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:860)
  at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:757)
  at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1056)
  at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:229)
  at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137)
  at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104)
  at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)
  at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79)
  at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54)
  at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)
  at com.sun.grizzly.ContextTask.run(ContextTask.java:71)
  at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532)
  at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513)
  at java.lang.Thread.run(Thread.java:722)

INFO: -->  In constructor for TableBeanLazy
INFO: -->  In initialise for TableBeanLazy
INFO: -->  In populateRandomCars for TableBeanLazy
INFO: -->  In constructor for TableBeanLazy
INFO: -->  In initialise for TableBeanLazy
INFO: -->  In populateRandomCars for TableBeanLazy
INFO: -->  In constructor for TableBeanLazy
INFO: -->  In initialise for TableBeanLazy
INFO: -->  In populateRandomCars for TableBeanLazy
INFO: java.lang.ArithmeticException: / by zero
java.lang.ArithmeticException: / by zero
  at org.primefaces.model.LazyDataModel.setRowIndex(LazyDataModel.java:62)
  at org.primefaces.component.api.UIData.setRowModel(UIData.java:409)
  at org.primefaces.component.api.UIData.setRowIndex(UIData.java:401)
  at org.primefaces.component.api.UIData.processChildren(UIData.java:289)
  at org.primefaces.component.api.UIData.processPhase(UIData.java:261)
  at org.primefaces.component.api.UIData.processUpdates(UIData.java:253)
  at org.primefaces.component.datatable.DataTable.processUpdates(DataTable.java:550)
  at com.sun.faces.context.PartialViewContextImpl$PhaseAwareVisitCallback.visit(PartialViewContextImpl.java:510)
  at com.sun.faces.component.visit.PartialVisitContext.invokeVisitCallback(PartialVisitContext.java:183)
  at org.primefaces.component.api.UIData.visitTree(UIData.java:639)
  at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
  at javax.faces.component.UIForm.visitTree(UIForm.java:344)
  at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
  at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
  at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
  at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
  at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
  at javax.faces.component.UIComponent.visitTree(UIComponent.java:1601)
  at com.sun.faces.context.PartialViewContextImpl.processComponents(PartialViewContextImpl.java:376)
  at com.sun.faces.context.PartialViewContextImpl.processPartial(PartialViewContextImpl.java:252)
  at javax.faces.context.PartialViewContextWrapper.processPartial(PartialViewContextWrapper.java:183)
  at javax.faces.component.UIViewRoot.processUpdates(UIViewRoot.java:1229)
  at com.sun.faces.lifecycle.UpdateModelValuesPhase.execute(UpdateModelValuesPhase.java:78)
  at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
  at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
  at javax.faces.webapp.FacesServlet.service(FacesServlet.java:593)
  at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1550)
  at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:281)
  at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
  at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:655)
  at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595)
  at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:161)
  at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:331)
  at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:231)
  at com.sun.enterprise.v3.services.impl.ContainerMapper$AdapterCallable.call(ContainerMapper.java:317)
  at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:195)
  at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:860)
  at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:757)
  at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1056)
  at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:229)
  at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137)
  at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104)
  at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)
  at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79)
  at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54)
  at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)
  at com.sun.grizzly.ContextTask.run(ContextTask.java:71)
  at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532)
  at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513)
  at java.lang.Thread.run(Thread.java:722)

INFO: -->  In constructor for TableBeanLazy
INFO: -->  In initialise for TableBeanLazy
INFO: -->  In populateRandomCars for TableBeanLazy
INFO: -->  In constructor for TableBeanLazy
INFO: -->  In initialise for TableBeanLazy
INFO: -->  In populateRandomCars for TableBeanLazy
INFO: -->  In constructor for TableBeanLazy
INFO: -->  In initialise for TableBeanLazy
INFO: -->  In populateRandomCars for TableBeanLazy
INFO: -->  In constructor for TableBeanLazy
INFO: -->  In initialise for TableBeanLazy
INFO: -->  In populateRandomCars for TableBeanLazy
INFO: -->  In constructor for TableBeanLazy
INFO: -->  In initialise for TableBeanLazy
INFO: -->  In populateRandomCars for TableBeanLazy

questionAnswers(1)

yourAnswerToTheQuestion