About Hebert Coelho

Senior Java Development, with 4 certifications and a published book about JSF (portuguese only). Founder of the blog uaiHebert.com visited from more than 170 different countries.

Lazy JSF Primefaces Datatable Pagination – Part 1

Today we will do JSF datatable pagination with a Lazy List with a view scoped managed bean. What all those words/expressions mean?

There are several JSF frameworks today that provide datatables with a ready pagination, columns sorter and others functionalities. Today we will use the Primefaces datatable.

Usually the datatables will put the displayed List, with the entities, inside the user http session. Increasing the objects inside the user session will have a direct impact on the server performance; each user that displays a datatable, that keeps a list in the session, will be allocating more and more memory in the server.

To look like real life, our post will use JPA and HSQLDB as database, and we will use JPQL to query the data.

In the end of this post you will find the link to download the source code.

We will use:

  • JSF 2.0 – JBoss 7 Implementation
  • JBoss 7.1 – the code of this post should be applied to all servers
  • Eclipse Indigo
  • JPA 2.0 – JBoss 7 Implementation
  • HSQLDB (2.2.8) – The HSQL it is a memory database, it will be easier to run it.
  • Primefaces 3.2 

This post is not about good development practices nor about adding classes layers of project modeling. I just intend to show how to do a pagination without a session managed bean.

We will have only one entity that will be persisted, the Player class. Bellow the class code:

package com.model;

import java.io.Serializable;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Entity
public class Player implements Serializable{

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int id;

    private String name;
    private int age;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public int hashCode() {
        return getId();
    }

    @Override
    public boolean equals(Object obj) {
        if(obj instanceof Player){
            Player player = (Player) obj;
            return player.getId() == getId();
        }

        return false;
    }
}

We will need to create a persistence.xml file inside the “src/META-INF” folder:

<?xml version="1.0" encoding="UTF-8"?>

<persistence version="2.0"
    xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">

    <persistence-unit name="JSFPU" transaction-type="JTA">
        <jta-data-source>java:/JSFDS</jta-data-source>

        <properties>
            <property name="hibernate.show_sql" value="false" />
            <property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect" />
            <property name="hibernate.connection.shutdown" value="true" />
            <property name="hibernate.hbm2ddl.auto" value="create-drop" />
        </properties>
    </persistence-unit>
</persistence>

To abstract the database transaction we will use a class named MyTransaction:

package com.connection;

import java.io.Serializable;

import javax.persistence.EntityManager;
import javax.transaction.HeuristicMixedException;
import javax.transaction.HeuristicRollbackException;
import javax.transaction.NotSupportedException;
import javax.transaction.RollbackException;
import javax.transaction.SystemException;

public class MyTransaction implements Serializable {

    /**
     *
     */
    private static final long serialVersionUID = 1L;

    private Connection connection = new Connection();   

    public void begin() throws NotSupportedException, SystemException {
        connection.begin();
    }

    public void commit() throws RollbackException, HeuristicMixedException, HeuristicRollbackException, SecurityException, IllegalStateException,
            SystemException {
        connection.commit();
    }

    public int getStatus() throws SystemException {
        return connection.getStatus();
    }

    public void rollback() throws IllegalStateException, SecurityException, SystemException {
        connection.rollback();
    }

    public void setRollbackOnly() throws IllegalStateException, SystemException {
        connection.setRollbackOnly();
    }

    public void setTransactionTimeout(int timeout) throws SystemException {
        connection.setTransactionTimeout(timeout);
    }

    public static MyTransaction getNewTransaction() {
        return new MyTransaction();
    }

    public EntityManager getEntityManager() {
        return connection.getEntityManager();
    }
}

You can see in the code above that the class is just an abstraction to the database connection; it will help us with the database queries. You could use any type of connection or you could use even a EJB to be avoiding this manually connection management.

Check the Connection class code:

package com.connection;

import java.io.Serializable;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.persistence.EntityManager;
import javax.transaction.HeuristicMixedException;
import javax.transaction.HeuristicRollbackException;
import javax.transaction.NotSupportedException;
import javax.transaction.RollbackException;
import javax.transaction.SystemException;
import javax.transaction.UserTransaction;

public class Connection implements Serializable {

    private static final long serialVersionUID = 1L;

    /**
     * Get the user transaction by JNDI
     *
     * @return the user transaction
     */
    public UserTransaction getUserTransaction() {
        UserTransaction ut = null;
        try {
            Context c = new InitialContext();
            ut = (UserTransaction) c.lookup("java:comp/UserTransaction");
        } catch (Exception e) {
            e.printStackTrace();
        }

        return ut;
    }

    /**
     * Get the EntityManayger by JNDI
     *
     * @return the entity manager
     */
    public EntityManager getEntityManager() {
        EntityManager em = null;

        try {
            Context initCtx = new InitialContext();
            // The JSFPU must be written in the web.xml
            em = (EntityManager) initCtx.lookup("java:comp/env/JSFPU");
        } catch (Exception e) {
            e.printStackTrace();
        }

        return em;
    }

    public void begin() throws NotSupportedException, SystemException {
        getUserTransaction().begin();
    }

    public void commit() throws SecurityException, IllegalStateException, RollbackException, HeuristicMixedException, HeuristicRollbackException, SystemException {
        getUserTransaction().commit();
    }

    public int getStatus() throws SystemException {
        return getUserTransaction().getStatus();
    }

    public void rollback() throws IllegalStateException, SecurityException, SystemException {
        getUserTransaction().rollback();
    }

    public void setRollbackOnly() throws IllegalStateException, SystemException {
        getUserTransaction().setRollbackOnly();
    }

    public void setTransactionTimeout(int timeout) throws SystemException {
        getUserTransaction().setTransactionTimeout(timeout);
    }
}

We could use an injected UserTransaction by the JSF but we chose to use JNDI lookup. There are several Primefaces calls that are invoked outside the JSF context, you may get some NullPointerException if you try to access the references that should be injected. There are several ways to work with this issue, but we will use the JNDI Lookup to the EntityManager and to the UserTransaction.

Our last class will be the PlayerDAO:

package com.dao;

import java.io.Serializable;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.Query;

import com.connection.MyTransaction;
import com.model.Player;

public class PlayerDAO implements Serializable {

    private static final long serialVersionUID = 1L;
    private MyTransaction myTransaction;

    public PlayerDAO(MyTransaction transaction) {
        this.myTransaction = transaction;
    }

    /**
     * Find players in the DB
     *
     * @param startingAt the first "row" db that the query will search
     * @param maxPerPage the amount of records allowed per "trip" in the DB
     * @return a players java.util.List
     */
    @SuppressWarnings("unchecked")
    public List<Player> findPlayers(int startingAt, int maxPerPage) {
        EntityManager em = myTransaction.getEntityManager();

        // regular query that will search for players in the db
        Query query = em.createQuery("select p from Player p");
        query.setFirstResult(startingAt);
        query.setMaxResults(maxPerPage);

        return query.getResultList();
    }

    /**
     * Creates 100 players in the DB
     */
    public void create100Players() {
        EntityManager em = myTransaction.getEntityManager();

        Player player;

        for (int x = 0; x < 100; x++) {
            player = new Player();
            player.setName("Player: " + x);
            player.setAge(x);
            em.persist(player);
        }

        em.flush();
    }

    /**
     * Sum the number of players in the DB
     *
     * @return an int with the total
     */
    public int countPlayersTotal() {
        EntityManager em = myTransaction.getEntityManager();
        Query query = em.createQuery("select COUNT(p) from Player p");

        Number result = (Number) query.getSingleResult();

        return result.intValue();
    }
}

In the PlayerDAO class we have only 3 methods to work with our pagination. Notice that there is no method to list all the players in our database.

Create the folder “YOU_JBOSS/modules/org/hsqldb/main“. Inside this folder create a file named “module.xml“. Write the code bellow inside the “module.xml” file:

<module xmlns="urn:jboss:module:1.0" name="org.hsqldb">
    <resources>
        <resource-root path="hsqldb.jar" />
    </resources>
    <dependencies>
        <module name="javax.api" />
        <module name="javax.transaction.api" />
    </dependencies>
</module>

Copy the “hsqldb.jar” file to the folder “main” that you just created. This file you will find inside the HSQLDB jar you download in the path “hsqldb-2.2.8.zip/hsqldb-2.2.8/hsqldb/lib“.

Edit the file “YOU_JBOSS/standalone/configuration/standalone.xml” and add the code bellow in the “datasources” node:

<datasource jndi-name="java:/JSFDS" pool-name="JSFDS_POOL"
    enabled="true" jta="true" use-java-context="true" use-ccm="true">
    <connection-url>
        jdbc:hsqldb:mem:jsfinmemory
    </connection-url>
    <driver>
        hsqldb
    </driver>
    <pool>
        <prefill>false</prefill>
        <use-strict-min>false</use-strict-min>
        <flush-strategy>FailingConnectionOnly</flush-strategy>
    </pool>
    <security>
        <user-name>
            sa
        </user-name>
        <password>
        </password>
    </security>
</datasource>

In the drivers node add:

<driver name="hsqldb" module="org.hsqldb"/>

Reference: Lazy JSF Datatable Pagination (Primefaces) from our JCG partner Hebert Coelho at the uaiHebert blog.

Related Whitepaper:

Functional Programming in Java: Harnessing the Power of Java 8 Lambda Expressions

Get ready to program in a whole new way!

Functional Programming in Java will help you quickly get on top of the new, essential Java 8 language features and the functional style that will change and improve your code. This short, targeted book will help you make the paradigm shift from the old imperative way to a less error-prone, more elegant, and concise coding style that’s also a breeze to parallelize. You’ll explore the syntax and semantics of lambda expressions, method and constructor references, and functional interfaces. You’ll design and write applications better using the new standards in Java 8 and the JDK.

Get it Now!  

2 Responses to "Lazy JSF Primefaces Datatable Pagination – Part 1"

  1. Here’s a LazyList implementation that can be used wherever normal Lists are accpeted:

    http://www.ninthavenue.com.au/blog/paging-large-data-sets-with-a-lazylist

  2. sb says:

    Do u know how to update pagelink in each load in a lazy loading datatable. Say there are 3 page links. When user clicks on 3rd button the page links will be increased to 6.

Leave a Reply


+ five = 10



Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use | Privacy Policy
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.

Sign up for our Newsletter

20,709 insiders are already enjoying weekly updates and complimentary whitepapers! Join them now to gain exclusive access to the latest news in the Java world, as well as insights about Android, Scala, Groovy and other related technologies.

As an extra bonus, by joining you will get our brand new e-books, published by Java Code Geeks and their JCG partners for your reading pleasure! Enter your info and stay on top of things,

  • Fresh trends
  • Cases and examples
  • Research and insights
  • Two complimentary e-books