title: How to implement general pagination
body: <p>I am not looking for a Hibernate/JPA/JDBC implementation, but for a general design pattern. </p>
  
  <p>Googling "pagination" gives me loads of information, lot of interesting articles that explain how to implement pagination on the UI and various implementations which more or less do the same.</p>
  
  <p>Since I am using Spring 3.0.5, and I stumbled this good reference article <a href="https://stackoverflow.com/questions/2245035/how-to-implement-pagination-in-spring-mvc-3">How to implement pagination in Spring MVC 3</a>. </p>
  
  <p>Simple bean:</p>
  
  <pre><code>public class Person{
       private String personName;
       private int age;
       // ...
  }
  </code></pre>
  
  <p>A simple DAO interface:</p>
  
  <pre><code>public interface PersonDAO{
     Set&lt;Person&gt; getAllPersons(int start, int limit,String orderBy);
     Set&lt;Person&gt; findPersonsByName(String name, int start, int limit,String orderBy);
  }
  </code></pre>
  
  <p>And the hibernate implementation</p>
  
  <pre><code>   @Repository
     public class PersonDAOImpl implements PersonDAO {
  
          @Autowired(required = true)
      private SessionFactory sessionFactory;
  
          public Set&lt;Person&gt; getAllPersons(int start, int limit, String orderBy){
                  Criteria crit = sessionFactory.getCurrentSession().createCriteria(Person.class);
                  crit.setFirstResult(start);
                  crit.setMaxResults(limit);
                  crit.addOrder(Order.asc("personName"));
                  return new LinkedHashSet&lt;Person&gt;(crit.list());
          }
  
  
          public Set&lt;Person&gt; findPersonsByName(String name, int start, int limit, String orderBy){
                  Criteria crit = sessionFactory.getCurrentSession().createCriteria(Person.class);
                  crit.add(Restrictions.eq("name", name));
                  crit.setFirstResult(start);
                  crit.setMaxResults(limit);
                  crit.addOrder(Order.asc(orderBy));
                  return new LinkedHashSet&lt;Person&gt;(crit.list());
           }
  </code></pre>
  
  <p>Now, I am thinking if I have to include similar parameters across all the interface then there is something really wrong here. Either I can wrap the request in a request bean object and pass this bean to the methods, something like this</p>
  
  <pre><code>public class PersonRequest{
     private int start;
     private int limit;
     private String orderBy;
     private String name;
     // ...
  }
  </code></pre>
  
  <p>And subsequently</p>
  
  <pre><code>public interface PersonDAO{
     Set&lt;Person&gt; getAllPersons(PersonRequest request);
     Set&lt;Person&gt; findPersonsByName(PersonRequest request);
  }
  </code></pre>
  
  <p>But this too seems unnatural, for some reason. Then I am thinking of varargs in Java </p>
  
  <pre><code>public interface PersonDAO{
     Set&lt;Person&gt; getAllPersons(Object... params);
     Set&lt;Person&gt; findPersonsByName(String name,Object... params);
  }
  
  
     @Repository
     public class PersonDAOImpl implements PersonDAO {
  
          @Autowired(required = true)
      private SessionFactory sessionFactory;
  
  
  
          public Set&lt;Person&gt; getAllPersons(Object... params){
                  Criteria crit = sessionFactory.getCurrentSession().createCriteria(Person.class);
                  crit.setFirstResult((Integer)params[0]);
                  crit.setMaxResults((Integer)params[1]);
                  crit.addOrder(Order.asc("personName"));
                  return new LinkedHashSet&lt;Person&gt;(crit.list());
          }
  
  
          public Set&lt;Person&gt; findPersonsByName(String name, Object... params){
                  Criteria crit = sessionFactory.getCurrentSession().createCriteria(Person.class);
                  crit.add(Restrictions.eq("name", name));
                  crit.setFirstResult((Integer)params[0]);
                  crit.setMaxResults((Integer)params[1]);
                  crit.addOrder(Order.asc((String)params[2]));
                  return new LinkedHashSet&lt;Person&gt;(crit.list());
           }
  </code></pre>
  
  <p>This too seems bit flimsy, for some reason I keep thinking bridge pattern could be helpful but still is distant unfit.</p>
  
  <p>Any idea how you would deal with this?</p>