Member Menu
 
 Monthly JBoss newsletter:
 
Hibernate Books
CaveatEmptor

paginationCode


import org.apache.log4j.Logger;
import java.util.List;

/**
 * @author Pietro Polsinelli ppolsinelli@open-lab.com 
 */
public interface Page {

  boolean isFirstPage();

  boolean isLastPage();

  boolean hasNextPage();

  boolean hasPreviousPage();

  int getLastPageNumber();

  List getThisPageElements();

  Logger getLogger();

  int getTotalNumberOfElements();

  int getThisPageFirstElementNumber();

  int getThisPageLastElementNumber();

  int getNextPageNumber();

  int getPreviousPageNumber();

  int getPageSize();

  int getPageNumber();

  List getAllElements();  

}

package org.jblooming.page;

import org.apache.log4j.Logger;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.ScrollMode;
import org.hibernate.ScrollableResults;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * @author Pietro Polsinelli ppolsinelli@open-lab.com
 */
public class HibernatePage implements Page {

  protected Query query;

  protected List elements;
  protected int pageSize;
  protected int pageNumber;
  protected int totalElements = -1;

  public static Set jdbcClassesSupportingScrollCursors = new HashSet();
  private ScrollableResults scrollableResults;
  public static final int DEFAULT_PAGE_SIZE = 10 ;

  private HibernatePage(int pageNumber, int pageSize) {
    this.pageNumber = pageNumber;
    this.pageSize = pageSize;
  }


  public boolean isFirstPage() {
    return getPageNumber() == 0;
  }

  public boolean isLastPage() {
    return getPageNumber() >= getLastPageNumber();
  }

  public boolean hasNextPage() {
    return !isLastPage();
  }

  public boolean hasPreviousPage() {
    return getPageNumber() > 0;
  }

  public int getLastPageNumber() {

    double totalResults = new Integer(getTotalNumberOfElements()).doubleValue();
    return new Double(Math.floor(totalResults / getPageSize())).intValue();
  }

  public List getThisPageElements() {
    return elements;
  }

  public Logger getLogger() {
     //WARN: THIS CODE MUST BE REPLACED
    return Logger.getLogger("platformLogger");
  }

  public int getTotalNumberOfElements() {
    return totalElements;
  }

  public int getThisPageFirstElementNumber() {
    return getPageNumber() * getPageSize() + 1;
  }

  public int getThisPageLastElementNumber() {
    int fullPage = getThisPageFirstElementNumber() + getPageSize() - 1;
    return getTotalNumberOfElements() < fullPage ?
            getTotalNumberOfElements() :
            fullPage;
  }

  public int getNextPageNumber() {
    return getPageNumber() + 1;
  }

  public int getPreviousPageNumber() {
    return getPageNumber() - 1;
  }

  public int getPageSize() {
    return pageSize;
  }

  public int getPageNumber() {
    return pageNumber;
  }

  public List getAllElements() {
    HibernatePage pageTmp = getHibernatePageInstance(query,1,getTotalNumberOfElements());
    return pageTmp.getThisPageElements();
  }


  public static HibernatePage getHibernatePageInstance(Query query, int pageNumber, int pageSize) {

    return getHibernatePageInstance(query, pageNumber, pageSize, [put here the driver_class of your Hibernate configuration]);
  }

  public static HibernatePage getHibernatePageInstance(Query query,
                                                       int pageNumber,
                                                       int pageSize,
                                                       String driverClass) {

    if (query.getQueryString().toLowerCase().indexOf("order by")==-1) {
     // WARN IN SOME WAY: warn("Using pagination without order by can lead to inconsistent results, for example on certain Oracle instances: "+query.getQueryString());
    }

    if (jdbcClassesSupportingScrollCursors.contains(driverClass))
      return HibernatePage.getScrollPageInstanceWithTotalByScroll(query, pageNumber, pageSize);
    else
      return HibernatePage.getScrollPageInstanceWithTotalByList(query, pageNumber, pageSize);
  }

  /**
   * Construct a new HibernatePage. HibernatePage numbers are zero-based so the
   * first page is page 0.
   *
   * @param query      the Hibernate Query
   * @param pageNumber the page number (zero-based);
   *                   if Integer.MAX_VALUE will return the last page for the query
   * @param pageSize   the number of results to display on the page
   */
  protected static HibernatePage getScrollPageInstanceWithTotalByScroll(Query query, int pageNumber, int pageSize) {

    HibernatePage sp = new HibernatePage(pageNumber, pageSize);
    sp.query = query;
    try {
      sp.scrollableResults = query.scroll(ScrollMode.SCROLL_SENSITIVE);
      sp.scrollableResults.last();
      sp.totalElements = sp.scrollableResults.getRowNumber();

      sp.fixThisPageElements();
      sp.scrollableResults.close();
    } catch (HibernateException e) {
      sp.getLogger().error("Failed to create ScrollPage by getScrollPageInstanceWithTotalByScroll: " + e.getMessage());
      throw new RuntimeException(e);
    }

    return sp;
  }


  /**
   * Construct a new HibernatePage. HibernatePage numbers are zero-based so the
   * first page is page 0.
   *
   * @param query      the Hibernate Query
   * @param pageNumber the page number (zero-based);
   *                   if Integer.MAX_VALUE will return the last page for the query
   * @param pageSize   the number of results to display on the page
   */
  protected static HibernatePage getScrollPageInstanceWithTotalByList(Query query, int pageNumber, int pageSize) {

    HibernatePage sp = new HibernatePage(pageNumber, pageSize);
    sp.query = query;
    try {
      //bacame useless
      //sp.scrollableResults = query.scroll(ScrollMode.FORWARD_ONLY);
      sp.totalElements = sp.calculateTotalElementsByList();
      sp.fixThisPageElements();

    } catch (HibernateException e) {
      sp.getLogger().error("Failed to create ScrollPage by getScrollPageInstanceWithTotalByQuery: " + e.getMessage());
      throw new RuntimeException(e);
    }

    return sp;
  }

  private void fixThisPageElements() throws HibernateException {

    if (this.pageSize<=0)
      this.pageSize=HibernatePage.DEFAULT_PAGE_SIZE;

    if (Integer.MAX_VALUE == this.pageNumber)
      this.pageNumber = (getTotalNumberOfElements() / this.pageSize);
    else if (pageNumber>(totalElements/pageSize))
      pageNumber = totalElements/pageSize;
    query = query.setFirstResult(this.pageNumber * this.pageSize);
    query = query.setMaxResults(this.pageSize);
    elements = query.list();
  }

  private int calculateTotalElementsByList() throws HibernateException {

    return query.list().size()-1;

  }
}

package org.jblooming.page;

import org.apache.log4j.Logger;

import java.util.List;

/**
 * @author Pietro Polsinelli ppolsinelli@open-lab.com
 */
public class ListPage implements Page {

  private List elements;
  private int pageSize;
  private int pageNumber;

  /**
   * Construct a new ListPage. ListPage numbers are zero-based, so the
   * first page is page 0.
   *
   * @param pageNumber the page number (zero-based);
   *                   if Integer.MAX_VALUE will return the last page for the query
   * @param pageSize   the number of results to display on the page
   */
  public ListPage(List elements, int pageNumber, int pageSize) {
    this.elements = elements;
    this.pageSize = pageSize;
    this.pageNumber = pageNumber;
    if (Integer.MAX_VALUE == this.pageNumber)
      this.pageNumber = (getTotalNumberOfElements() / this.pageSize);
    else if (this.pageNumber > (getTotalNumberOfElements() / this.pageSize))
      this.pageNumber = (elements.size()-1) / this.pageSize;

  }

  public boolean isFirstPage() {
    return getPageNumber() == 0;
  }

  public boolean isLastPage() {
    return getPageNumber() >= getLastPageNumber();
  }

   public boolean hasNextPage() {
    return !isLastPage();
  }

  public boolean hasPreviousPage() {
    return getPageNumber() > 0;
  }

  public int getLastPageNumber() {
/*
* We use the Math.floor() method because page numbers are zero-based
* (i.e. the first page is page 0).
*/
    double totalResults = new Integer(getTotalNumberOfElements()).doubleValue();
    return new Double(Math.floor(totalResults / getPageSize())).intValue();
  }

  public List getThisPageElements() {

/*
* Since we retrieved one more than the specified pageSize when the
* class was constructed, we now trim it down to the pageSize if a next
* page exists.
*/
    final int start = getPageNumber() * getPageSize();
    return elements.subList(Math.min(start, getTotalNumberOfElements() + 1),
            Math.min(start + getPageSize(), getTotalNumberOfElements() + 1));
  }

  public Logger getLogger() {
    //WARN: THIS CODE MUST BE REPLACED
    return Logger.getLogger("platformLogger");    
  }

  /**
   * this is 0-based, differently from list.size();
   */
  public int getTotalNumberOfElements() {
    return elements.size() - 1;
  }

  public int getThisPageFirstElementNumber() {
    return getPageNumber() * getPageSize() + 1;
  }

  public int getThisPageLastElementNumber() {
    int fullPage = getThisPageFirstElementNumber() + getPageSize() - 1;
    return getTotalNumberOfElements() < fullPage ?
            getTotalNumberOfElements() :
            fullPage;
  }

  public int getNextPageNumber() {
    return getPageNumber() + 1;
  }

  public int getPreviousPageNumber() {
    return getPageNumber() - 1;
  }


  public int getPageSize() {
    return pageSize;
  }

  public int getPageNumber() {
    return pageNumber;
  }

 public List getAllElements() {
    return elements;
  }

}


© Copyright 2006, Red Hat Middleware, LLC. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc. [Privacy Policy]