Ron’s Weblog

Mostly related to java, javascript and web development.

Don’t forget an "order by" for pagination queries

with one comment

I’ve seen this many times in web-based applications that use paginated results.

If you’re using Oracle, the general form of such a query is :

   select * from
   (
      select /*+ FIRST_ROWS(n) */ a.*, ROWNUM rnum from
          (your_query_goes_here) a
      where  ROWNUM <=:MAX_ROW_TO_FETCH
   )
  where rnum  >= :MIN_ROW_TO_FETCH;

While doing this with JDBC/SQL is easy enough-if you’re using Hibernate HQL (with the appropriate Oracle Dialect), you can also take advantage of this feature. For example:

Query q = "from Customer c order by c.lastName";
q.setFirstResult(10);
q.setMaxResults(30);
List results = q.list();

For this query to work correctly, all the time, it is important to always sort by a unique column. In the example above, “lastName” will likely have duplicate values. There is no way to guarantee the order of the returned rows unless we include a unique ‘order by’ clause. If a unique column is not available, in many cases, you can just sort by ROWID. See this article here for more on rownum.The modified HQL would look like

"from Customer c
order by c.lastName, c.rowId"

Of course, you would have to map a java property “rowId” to the pseudo-column “ROWID”.
While mapping it in hibernate, be sure to mark it as update=”false” and insert=”false”, since you cannot update the ROWID column.

Written by Ron Francis

October 16, 2007 at 7:25 pm

One Response

Subscribe to comments with RSS.

  1. When i tried to use a query of the above type in hsql,
    I got an error saying that it cannot find a column named rownum.

    Puneet

    February 22, 2010 at 8:39 pm


Leave a comment