Incorrect Partitioning

I have an application using JSF2.0, Spring3 and Hibernate4.

I show the values ​​in a Primfaces 3.4.2 datatable file, the problem is that when I click on pagination, the data series always remain in the first 10 records. It does not display the next 10 entries.

My datatable code

<h:form> <p:dataTable id="dataTable" var="req" value="#{reqMB.myList}" paginator="true" rows="10" paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}" rowsPerPageTemplate="5,10,15"> <f:facet name="header"> </f:facet> <p:column> <f:facet name="header"> <h:outputText value="XXX" /> </f:facet> <h:outputText value="#{req.bbbb}" /> </p:column> <p:column> <f:facet name="header"> <h:outputText value="XXXXS" /> </f:facet> <h:outputText value="#{req.kkjj}" /> </p:column> <p:column> <f:facet name="header"> <h:outputText value="XXXXXOO" /> </f:facet> <h:outputText value="#{req.nnnn}" /> </p:column> <p:column> <f:facet name="header"> <h:outputText value="XXXXKK" /> </f:facet> <h:outputText value="#{req.kkkk}" /> </p:column> <p:column> <f:facet name="header"> <h:outputText value="XKKKK" /> </f:facet> <h:outputText value="#{req.pppp}" /> </p:column> <p:column> <f:facet name="header"> <h:outputText value="LLLL" /> </f:facet> <h:outputText value="#{req.llll}" /> </p:column> </p:dataTable> </h:form> 

Managedbean

 @Named("reqMB") @Scope("request") public class MyBean implements Serializable { private static final long serialVersionUID = 1L; @Inject MyService myService; List<MyClass> myList; public List<MyClass> getMyList() { try { myList= new ArrayList<MyClass>(); myList.addAll(getMyService().getMymethod()); } catch (Exception e) { e.printStackTrace(); } return myList; } 

How can I solve this problem?

Update 1

I noticed that when I show a small number of records, pagination works fine, but when I show records more than 1300, then pagination does not work.

+4
source share
2 answers

I just tried 30,000 entries and everything worked out fine. However, it is worth noting that the getMyList method is called many times (6 in my case in the rendering response phase), and each time it is called your bean, it selects / generates a new list, and this may be the part that caused the problem (although I tried to create a new list in my getter method, but it worked fine).

Generally speaking, it is recommended that you do not specify codes related to business logic. Instead, in many cases, it would be better to populate the list in the @PostConstruct method or elsewhere. Please see Post made by BalusC and this may be helpful. Why JSF calls getters several times Also you can read this for lazy loading Effective JSF breakdown

Below are my test codes:

 <h:body> <h:form> <p:dataTable id="dataTable" var="car" value="#{tableBean.cars}" paginator="true" rows="10" paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}" rowsPerPageTemplate="5,10,15"> <f:facet name="header"> Ajax Pagination </f:facet> <p:column> <f:facet name="header"> <h:outputText value="Model" /> </f:facet> <h:outputText value="#{car.model}" /> </p:column> <p:column> <f:facet name="header"> <h:outputText value="Manufacturer" /> </f:facet> <h:outputText value="#{car.manufacturer}" /> </p:column> <p:column> <f:facet name="header"> <h:outputText value="Other Information" /> </f:facet> <h:outputText value="#{car.otherInformation}" /> </p:column> </p:dataTable> </h:form> <ui:debug hotkey="x"/> </h:body> 

And this is bean support:

 @ManagedBean @RequestScoped public class TableBean implements Serializable { private List<Car> cars; @PostConstruct public void init() { System.out.println("A new backing bean has been created"); cars = new ArrayList<Car>(); populateRandomCars(cars, 300000); } private void populateRandomCars(List<Car> list, int size) { for (int i = 0; i < size; i++) { list.add(new Car(i, i, UUID.randomUUID().toString())); } } public List<Car> getCars() { //If i populate the list here I can still get the correct result. // cars = new ArrayList<Car>(); // populateRandomCars(cars, 30000); return cars; } public void setCars(List<Car> cars) { this.cars = cars; } } 

And finally, the model class:

 public class Car { private int manufacturer; private int model; private String otherInformation; public Car(int manufacturer, int model, String otherInformation){ this.manufacturer = manufacturer; this.model = model; this.otherInformation = otherInformation; } //Getters and Setters } 
+2
source

The problem is that you create each time a datatable when used this way:

 public List<MyClass> getMyList() { ... myList= new ArrayList<MyClass>(); ... } 

you need to initialize the first attribute myList, for example, you can use @PostContruct

 @PostConstruct public void init() { myList= new ArrayList<MyClass>(); } 

then you can use:

 public List<MyClass> getMyList() { return myList } 

This will work even with Lazy datatables

+2
source

All Articles