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.

Do you want to know how to develop your skillset to become a Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

JPA Mini Book

Learn how to leverage the power of JPA in order to create robust and flexible Java applications. With this Mini Book, you will get introduced to JPA and smoothly transition to more advanced concepts.

JVM Troubleshooting Guide

The Java virtual machine is really the foundation of any Java EE platform. Learn how to master it with this advanced guide!

Given email address is already subscribed, thank you!
Oops. Something went wrong. Please try again later.
Please provide a valid email address.
Thank you, your sign-up request was successful! Please check your e-mail inbox.
Please complete the CAPTCHA.
Please fill in the required fields.

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 − 3 =



Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use | Privacy Policy | Contact
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.
Do you want to know how to develop your skillset and become a ...
Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

Get ready to Rock!
You can download the complementary eBooks using the links below:
Close