Red Hat

Pagination in Hibernate and EJB3

Posted by Gavin King    |       |    Tagged as

Just had an interesting discussion on ejb3-feedback@sun.com, started by David Cherryhomes, which saw me stupidly insistingthat something can't be done when in fact, now that I think about it, /I realize I've actually done it before/, and that even the Hibernate AdminApp example uses this pattern!

So, just so I don't forget this pattern again, I'm going to write it down, and also write a reuseable class implementing it.

The basic problem is pagination. I want to display next and previous buttons to the user, but disable them if there are no more, or no previous query results. But I don't want to retrieve all the query results in each request, or execute a separate query to count them. So, here's the correct approach:

public class Page {
   
   private List results;
   private int pageSize;
   private int page;
   
   public Page(Query query, int page, int pageSize) {
       
       this.page = page;
       this.pageSize = pageSize;
       results = query.setFirstResult(page * pageSize)
           .setMaxResults(pageSize+1)
           .list();
   
   }
   
   public boolean isNextPage() {
       return results.size() > pageSize;
   }
   
   public boolean isPreviousPage() {
       return page > 0;
   }
   
   public List getList() {
       return isNextPage() ?
           results.subList(0, pageSize-1) :
           results;
   }

}

You can return this object to your JSP, and use it in Struts, WebWork or JSTL tags. Getting a page in your persistence logic is as simple as:

public Page getPosts(int page) {
    return new Page( 
        session.createQuery("from Posts p order by p.date desc")
        page,
        40
    );
}

The Page class works in both Hibernate and EJB 3.0.

back to top