Wednesday, March 12, 2014

Implement pagination in JSF 2.x with Primefaces

Primefaces provids LazyDataModel which you can bind with DataTable object to provide very powerful pagination functionalities in the UI, including customizable pagination buttons, sorting functions, and multiple query criteria, and so on.
The way to use it is not difficult but there's not much information about it you can find in the documentation. The best starting point is to check the Primeface showcase at http://www.primefaces.org/showcase/ui/datatableLazy.jsf .
Steps to implement the support for LazyDataModel with JSF2.x can be briefly described as follows:

  1. Implement a child class (Let's call it ChildLazyDataModel) of LazyDataModel with one @Override method List load(int first, int pagesize, String sortfield, SortOrder sortorder, Map filters). This method will be invoked whenever pagination happens. Inside the method, 2 pieces of logic should be implemented:
    • The total result count should be set on the datamodel.
    • The result should be returned from the query.
  2. Build the JSF backing bean in the way that it contains an instance of ChildLazyDataModel. Let's call it PrimeBackingBean. The getter of the lazy data model will return a new instance.
  3. Bind the ChildLazyDataModel variable from PrimeBackingBean with the Primeface datatable object in the JSF files.

You can get some examples with EJB or DAO in the internet. But I didn't find much information on how to implement it with the setup of JSF2 and JPA. The tricky part is normally people inject JPA execution logic (query, update entities) into JSF managed beans, for example, PrimeBackingBean in our case. Such injection won't work for ChildLazyDataModel, as ChildLazyDataModel is not a container-manageable yet. I didn't try the option to make it container-manageable object yet. Instead, I used an easier alternative:

  • Inject the JPA execution bean into PrimeBackingBean.
  • Implement the constructor for ChildLazyDataModel with the parameter of JPA execution bean. The JPA execution bean instance can be used to do all the required queries.
  • In the getter for the lazy data model of PrimeBackingBean, instantiate new lazy data model by passing the injected JPA execution bean using the new constructor.

No comments: