PrimeFaces - DataTable Lazy Data Loading with Pagination and Filtering

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

This is an example of PrimeFaces lazy DataTable which has pagination and filters as well. We are going to use JPA, Hibernate and in-memory H2 database to persist/load data.

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" filterBy="#{employee.id}" filterMatchMode="contains">
        <h:outputText value="#{employee.id}"/>
    </p:column>

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

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

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

The managed bean

@ManagedBean
@RequestScoped
public class EmployeeBean {
  EmployeeLazyDataModel dataModel = new EmployeeLazyDataModel();

  public LazyDataModel<Employee> getModel() {
      return dataModel;
  }
}
@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() {
      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, filters);
      if (filters != null && filters.size() > 0) {
          //otherwise it will still show all page links; pages at end will be empty
          this.setRowCount(DataService.INSTANCE.getFilteredRowCount(filters));
      }
      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,
                                        Map<String, Object> filters) {
      EntityManager em = emf.createEntityManager();
      CriteriaBuilder cb = em.getCriteriaBuilder();
      CriteriaQuery<Employee> criteriaQuery = cb.createQuery(Employee.class);
      Root<Employee> root = criteriaQuery.from(Employee.class);
      CriteriaQuery<Employee> select = criteriaQuery.select(root);

      if (filters != null && filters.size() > 0) {
          List<Predicate> predicates = new ArrayList<>();
          for (Map.Entry<String, Object> entry : filters.entrySet()) {
              String field = entry.getKey();
              Object value = entry.getValue();
              if (value == null) {
                  continue;
              }

              Expression<String> expr = root.get(field).as(String.class);
              Predicate p = cb.like(cb.lower(expr),
                      "%" + value.toString().toLowerCase() + "%");
              predicates.add(p);
          }
          if (predicates.size() > 0) {
              criteriaQuery.where(cb.and(predicates.toArray
                      (new Predicate[predicates.size()])));
          }
      }

      TypedQuery<Employee> query = em.createQuery(select);
      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();
  }

  public int getFilteredRowCount(Map<String, Object> filters) {
      EntityManager em = emf.createEntityManager();
      CriteriaBuilder cb = em.getCriteriaBuilder();
      CriteriaQuery<Long> criteriaQuery = cb.createQuery(Long.class);
      Root<Employee> root = criteriaQuery.from(Employee.class);
      CriteriaQuery<Long> select = criteriaQuery.select(cb.count(root));

      if (filters != null && filters.size() > 0) {
          List<Predicate> predicates = new ArrayList<>();
          for (Map.Entry<String, Object> entry : filters.entrySet()) {
              String field = entry.getKey();
              Object value = entry.getValue();
              if (value == null) {
                  continue;
              }

              Expression<String> expr = root.get(field).as(String.class);
              Predicate p = cb.like(cb.lower(expr),
                      "%" + value.toString().toLowerCase() + "%");
              predicates.add(p);
          }
          if (predicates.size() > 0) {
              criteriaQuery.where(cb.and(predicates.toArray
                      (new Predicate[predicates.size()])));
          }
      }
      Long count = em.createQuery(select).getSingleResult();
      return count.intValue();
  }

}

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

mvn tomcat7:run-war

Output

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

DataTable Lazy Pagination With Filtering Select All Download
  • data-table-lazy-pagination-with-filtering
    • src
      • main
        • java
          • com
            • logicbig
              • example
        • resources
          • META-INF
        • webapp

See Also