title: How to reuse a Criteria object with hibernate?
body: <p>I'm trying to do query result pagination with hibernate and displaytag, and Hibernate <code>DetachedCriteria</code> objects are doing their best to stand in the way. Let me explain...</p>
  
  <p>The easiest way to do pagination with displaytag seems to be implementing the <code>PaginatedList</code> interface that has, among others, the following methods:</p>
  
  <pre><code>/* Gets the total number of results. */
  int getFullListSize();
  
  /* Gets the current page of results. */
  List getList();
  
  /* Gets the page size. */
  int getObjectsPerPage();
  
  /* Gets the current page number. */
  int getPageNumber();
  
  /* Get the sorting column and direction */
  String getSortCriterion();
  SortOrderEnum getSortDirection();
  </code></pre>
  
  <p>I'm thinking of throwing my PaginatedList implementation a Criteria object and let it work along theese lines...</p>
  
  <pre><code>getFullListSize() {
      criteria.setProjection(Projections.rowCount());
      return ((Long) criteria.uniqueResult()).intValue();
  }
  
  getList() {
      if (getSortDirection() == SortOrderEnum.ASCENDING) {
          criteria.addOrder(Order.asc(getSortCriterion());
      } else if (getSortDirection() == SortOrderEnum.DECENDING) {
          criteria.addOrder(Order.desc(getSortCriterion());
      }
      return criteria.list((getPageNumber() - 1) * getObjectsPerPage(),
                           getObjectsPerPage());
  }
  </code></pre>
  
  <p>But this doesn't work, because the <code>addOrder()</code> or the <code>setProjection()</code> calls modify the criteria object rendering it in-usable for the successive calls. I'm not entirely sure of the order of the calls, but the db throws an error on <code>getFullListSize()</code> trying to do a "<code>select count(*) ... order by ...</code>" which is obviously wrong.</p>
  
  <p>I think I could fix this by creating an object of my own to keep track of query conditions and rebuilding the Criteria object for each call, but that feels like reinventing yet another wheel. Is there a smarter way, possibly copying the Criteria initially passed in and working on that copy?</p>
  
  <p><strong><em>Update</em></strong>:
  It looks like <code>getList</code> is called first, and <code>getFullListSize</code> is called multiple times after, so, as soon as there's an ordering passed in, <code>getFullListSize</code> will fail. It would make sense to hit the db only once (in <code>getList</code> I'd say) and cache the results, with no need to copy/reset the <code>Criteria</code> object, but still...</p>
  
  <p><strong><em>Update (again)</em></strong>:
  Forget about that, once I've done the <code>count</code> I can't do the <code>select</code>, and vice versa. I really need two distinct <code>Criteria</code> objects.</p>