-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 1 post ] 
Author Message
 Post subject: Count found rows
PostPosted: Mon Jun 14, 2010 3:57 am 
Pro
Pro

Joined: Mon Apr 16, 2007 8:10 am
Posts: 246
Dear all,

I have a PHP application with lots of MySQL statements for which the number of rows retrieved by the statements (ignoring the limit keyword) is needed.

These MySQL statements make use of the SQL_CALC_FOUND_ROWS keyword.

Here is one such statement:

Code:
  function selectAll($start = false, $rows = false) {
    $sqlStatement = "SELECT SQL_CALC_FOUND_ROWS * FROM $this->tableName ORDER BY name";
    if ($rows) {
      if (!$start) {
        $start = 0;
      }
      $sqlStatement .= " LIMIT " . $start . ", " . $rows;
    } else if ($start) {
      $sqlStatement .= " LIMIT " . $start;
    }
    return($this->querySelect($sqlStatement));
  }


When this statement is performed, it returns a limited number of rows.

And right after that statement, this other statement is performed:

Code:
  // Count the number of rows of the last select statement
  // ignoring the LIMIT keyword if any
  // The SQL_CALC_FOUND_ROWS clause tells MySQL to calculate how many rows there would be
  // in the result set, disregarding any LIMIT clause with the number of rows later
  // retrieved using the SELECT FOUND_ROWS() statement
  function countFoundRows() {
    $sqlStatement = "SELECT FOUND_ROWS() as count";
    return($this->querySelect($sqlStatement));
  }


There are lots of such statements in the application so as to offer pagination support.

Now, I wonder how to do this in Hibernate.

I have the following dao classes:

Code:
@Transactional
public class AdminHibernateDao extends GenericHibernateDao<Admin, Serializable> implements AdminDao {

   @SuppressWarnings("unchecked")
   @Override
   public List<Admin> findLikePattern(String pattern) {
      pattern = "%" + pattern + "%";
      Criteria criteria = getSession().createCriteria(Admin.class);
      criteria.add(Restrictions.ilike("firstname", pattern))
      .add(Restrictions.ilike("lastname", pattern))
      .add(Restrictions.ilike("login", pattern))
      .add(Restrictions.ilike("email", pattern))
      .addOrder(Order.asc("firstname")).addOrder(Order.asc("lastname"));
      return criteria.list();
   }
}


Code:
@Transactional
public abstract class GenericHibernateDao<T, ID extends Serializable> implements GenericDao<T, ID> {

   private static Logger log = Logger.getLogger(GenericHibernateDao.class);

   private Class<T> persistentClass;
   private SessionFactory sessionFactory;

   @SuppressWarnings("unchecked")
   public GenericHibernateDao() {
      this.persistentClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
   }

   public void setSessionFactory(SessionFactory sessionFactory) {
      this.sessionFactory = sessionFactory;
   }

   public SessionFactory getSessionFactory() {
      if (sessionFactory == null) {
         throw new IllegalStateException("sessionFactory has not been set on DAO before usage");
      }
      return sessionFactory;
   }

   public Class<T> getPersistentClass() {
      return persistentClass;
   }
   
   @Override
   public Session getSession() {
      return getSessionFactory().getCurrentSession();
   }

   @SuppressWarnings("unchecked")
   @Override
   public T findById(ID id, boolean lock) {
      T entity;
      if (lock)
         entity = (T) getSession().load(getPersistentClass(), id, LockMode.UPGRADE);
      else
         entity = (T) getSession().load(getPersistentClass(), id);

      return entity;
   }

   @SuppressWarnings("unchecked")
   @Override
   public boolean isFoundById(ID id) {
      try {
         @SuppressWarnings("unused")
         T entity = (T) getSession().load(getPersistentClass(), id);
      } catch (ObjectNotFoundException e) {
         return false;
      }

      return true;
   }

   @Override
   public List<T> findAll() {
      return findObjectsByCriteria();
   }

   @Override
   public long countAllRows() {
      Criteria criteria = getSession().createCriteria(getPersistentClass());
      criteria.setProjection(Projections.rowCount());
      Integer count = (Integer) criteria.list().get(0);
      long itemCount = count.intValue();
      return itemCount;
   }

   @Override
   public long countFoundRows() {
      Criteria criteria = getSession().createCriteria(getPersistentClass());
      criteria.setProjection(Projections.rowCount());
       Integer count = (Integer) criteria.uniqueResult();
       long itemCount = count.intValue();
      return itemCount;
   }

   @SuppressWarnings("unchecked")
   @Override
   public List<T> findByExample(T exampleInstance, String... excludeProperty) {
      Criteria criteria = getSession().createCriteria(getPersistentClass());
      Example example = Example.create(exampleInstance);
      for (String exclude : excludeProperty) {
         example.excludeProperty(exclude);
      }
      criteria.add(example);
      return criteria.list();
   }

   @Override
   public T makePersistent(T entity) {
      getSession().saveOrUpdate(entity);
      return entity;
   }

   @Override
   public void makeTransient(T entity) {
      getSession().delete(entity);
   }

   public void flush() {
      getSession().flush();
   }

   public void clear() {
      getSession().clear();
   }

   @SuppressWarnings("unchecked")
   @Override
   public List<T> findObjectsByCriteria(Criterion... criterion) {
      Criteria criteria = getSession().createCriteria(getPersistentClass());
      for (Criterion c : criterion) {
         criteria.add(c);
      }
      return criteria.list();
   }

   @Override
   public T findObjectByCriteria(Criterion... criterion) {
      T object = null;
      List<T> results = findObjectsByCriteria(criterion);

      if (results.isEmpty()) {
         if (log.isDebugEnabled()) {
            log.debug("No search results found for: " + criterion);
         }
      } else {
         if (results.size() > 1) {
            if (log.isDebugEnabled()) {
               log.debug("The criterion : " + criterion + " should return only one result");
            }
         }
         object = results.get(0);
      }

      return object;
   }

   @SuppressWarnings("unchecked")
   @Override
   public T findObjectByCriteria(Criteria criteria) {
      T object = null;
      List<T> results = criteria.list();

      if (results.isEmpty()) {
         if (log.isDebugEnabled()) {
            log.debug("No search results found for the criteria : " + criteria);
         }
      } else {
         if (results.size() > 1) {
            if (log.isDebugEnabled()) {
               log.debug("The criteria : " + criteria + " should return only one result");
            }
         }
         object = results.get(0);
      }

      return object;
   }

}


I would like to offer pagination on the findLikePattern statement.

How to go to have all my findBy.. statements offering the number of found rows ?

Do you know of any strategy to have this feature on hundreds of different findBy... statements ?


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 1 post ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.