Primefaces数据表分页不起作用

时间:2012-12-18 16:32:40

标签: java spring hibernate jsf-2 primefaces

我有一个使用JSF2.0,Spring3和Hibernate4的应用程序。

我在Primefaces 3.4.2数据表中显示值,问题是当我点击分页时,数据表行始终保留在前10条记录中。它不显示接下来的10条记录。

我的数据表代码

<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;
    }

如何解决此问题?

更新1

我注意到当我显示少量记录时,分页工作正常,但是当我显示超过1300的记录时,分页不起作用。

2 个答案:

答案 0 :(得分:2)

我刚尝试了30000条记录,它运行正常。值得注意的一件事是,getMyList方法被多次调用(在我的情况下为渲染响应阶段为6),并且每次调用它都是bean获取/生成一个全新的列表,这可能是导致问题(虽然我试图在我的getter方法中生成一个新列表,但它工作正常)。

一般来说,建议不要在那里放置任何与业务逻辑相关的代码。相反,在许多情况下,最好在@PostConstruct方法或其他地方填充列表。请参阅BalusC制作的帖子,它可能会有所帮助。 Why JSF calls getters multiple times 你也可以阅读这个延迟加载 Efficient JSF Pagination

以下是我的测试代码:

<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>

这是支持bean:

@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;
    }
}

最后是模型类:

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 
}

答案 1 :(得分:2)

问题在于,当您以这种方式使用时,每次都会创建数据表:

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

您需要初始化第一个myList属性,例如您可以使用@PostContruct

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

然后,您可以使用:

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

这甚至适用于Lazy数据表