PrimeFaces - DataTable Pagination with Lazy Data Loading

[Updated: Aug 16, 2017, Created: Jun 11, 2017]

PrimeFaces also provides lazy data loading with DataTable pagination. This allows us not to load and display very large number of rows at once. To achieve lazy loading, we have to implement LazyDataModel. In following example, we are going to use JPA, Hibernate and H2 in-memory database to persist/load data during lazy pagination.

The view

src/main/webapp/index.xhtml

<p:dataTable var="employee" value="#{employeeBean.model}"
             paginator="true" rows="10"
             paginatorTemplate=
                     "{RowsPerPageDropdown} {FirstPageLink}
                     {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink}"
             rowsPerPageTemplate="5,10,15" lazy="true">
    <p:column headerText="Id">
        <h:outputText value="#{employee.id}"/>
    </p:column>

    <p:column headerText="Name">
        <h:outputText value="#{employee.name}"/>
    </p:column>

    <p:column headerText="Phone Number">
        <h:outputText value="#{employee.phoneNumber}"/>
    </p:column>

    <p:column headerText="Address">
        <h:outputText value="#{employee.address}"/>
    </p:column>
</p:dataTable>

The managed bean

@ManagedBean
@RequestScoped
public class EmployeeBean {
    .............
  public LazyDataModel<Employee> getModel(){
      return dataModel;
  }
}

In this example, our bean is also a JPA entity.

@Entity
public class Employee {
  @Id
  @SequenceGenerator(name = "eSGen", sequenceName = "employeeSeq",
          initialValue = 50)
  @GeneratedValue(generator = "eSGen")
  private long id;
  private String name;
  private String phoneNumber;
  private String address;
  //getters/setters
    .............
}

LazyDataModel implementation

public class EmployeeLazyDataModel extends LazyDataModel<Employee> {

  public EmployeeLazyDataModel(){
      System.out.println("--------- "+this+" -----------------");
      this.setRowCount(DataService.INSTANCE.getEmployeeTotalCount());
  }
  @Override
  public List<Employee> load(int first, int pageSize, String sortField,
                             SortOrder sortOrder, Map<String, Object> filters) {

      List<Employee> list = DataService.INSTANCE.getEmployeeList(first, pageSize);
      return list;
  }
}

DataService

public enum DataService {
  INSTANCE;
  private final EntityManagerFactory emf =
          Persistence.createEntityManagerFactory("employee-unit");

  DataService(){
      //persisting some data in database
      EntityManager em = emf.createEntityManager();
      em.getTransaction().begin();

      DataFactory dataFactory = new DataFactory();
      for (int i = 1; i < 100; i++) {
          Employee employee = new Employee();
          employee.setName(dataFactory.getName());
          employee.setPhoneNumber(String.format("%s-%s-%s", dataFactory.getNumberText(3),
                  dataFactory.getNumberText(3),
                  dataFactory.getNumberText(4)));
          employee.setAddress(dataFactory.getAddress() + "," + dataFactory.getCity());
          em.persist(employee);
      }

      em.getTransaction().commit();
      em.close();
  }

  public List<Employee> getEmployeeList(int start, int size){
      EntityManager em = emf.createEntityManager();
      Query query = em.createQuery("From Employee");
      query.setFirstResult(start);
      query.setMaxResults(size);
      List <Employee> list = query.getResultList();
      return list;
  }

  public int getEmployeeTotalCount() {
      EntityManager em = emf.createEntityManager();
      Query query = em.createQuery("Select count(e.id) From Employee e");
      return ((Long)query.getSingleResult()).intValue();
  }
}

To try examples, run embedded tomcat (configured in pom.xml of example project below):

mvn tomcat7:run-war

Output

On server console, you will see real-time hibernate logs during pagination:

   ....
Hibernate: select count(employee0_.id) as col_0_0_ from Employee employee0_
Hibernate: select employee0_.id as id1_0_, employee0_.address as address2_0_, employee0_.name as name3_0_, employee0_.phoneNumber as phoneNum4_0_ from Employee employee0_ limit ?
Hibernate: select count(employee0_.id) as col_0_0_ from Employee employee0_
Hibernate: select employee0_.id as id1_0_, employee0_.address as address2_0_, employee0_.name as name3_0_, employee0_.phoneNumber as phoneNum4_0_ from Employee employee0_ limit ?
Hibernate: select count(employee0_.id) as col_0_0_ from Employee employee0_
Hibernate: select employee0_.id as id1_0_, employee0_.address as address2_0_, employee0_.name as name3_0_, employee0_.phoneNumber as phoneNum4_0_ from Employee employee0_ limit ? offset ?
    ...

Note that, a new instance LazyDataModel is created on every pagination action.

Example Project

Dependencies and Technologies Used :

  • primefaces 6.1 primefaces
  • jsf-api 2.2.14: This is the master POM file for Oracle's Implementation of the JSF 2.2 Specification.
  • jsf-impl 2.2.14: This is the master POM file for Oracle's Implementation of the JSF 2.2 Specification.
  • h2 1.4.193: H2 Database Engine.
  • hibernate-core 5.2.8.Final: The core O/RM functionality as provided by Hibernate.
  • datafactory 0.8: Library to generate data for testing.
  • JDK 1.8
  • Maven 3.3.9

Primefaces DataTable Lazy Pagination Example Select All Download
  • data-table-lazy
    • src
      • main
        • java
          • com
            • logicbig
              • example
        • resources
          • META-INF
        • webapp

See Also