-->
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.  [ 5 posts ] 
Author Message
 Post subject: Pagination with Projection.rowCount() in a single call?
PostPosted: Mon May 21, 2007 3:14 pm 
Regular
Regular

Joined: Sat Jan 22, 2005 6:57 pm
Posts: 50
Location: Chicago
Is there a way within a construction of a single criteria object (and therefore a single sql statement) that not only gets a page of data with a firstResult, maxResults setting, but also a Projection.rowCount()?

I was on Matt Riable's wiki and saw his post:
http://raibledesigns.com/wiki/Wiki.jsp?page=HibernatePagination

He has code that looks like this:

Code:
Query q = s.createFilter( collection, "" ); // the trivial filter
q.setMaxResults(PAGE_SIZE);
q.setFirstResult(PAGE_SIZE * pageNumber);
q.setProjection( Projections.alias( Projections.rowCount(), "numResults" ) )
List page = q.list();


However, I cannot get that to work on Criteria objects. The returning resultset is always empty. When I remove the last projection line, I always get results so I know the criteria is good. I thought perhaps that "numResults" was a reserved keyword since there is no context as to what it is. But I guess it is not.

(tried this)
Code:
Criteria c = ...
c.setMaxResults(PAGE_SIZE);
c.setFirstResult(PAGE_SIZE * pageNumber);
c.setProjection( Projections.alias( Projections.rowCount(), "numResults" ) )
List page = c.list();


I have posted a question on the Oracle Forums to see if this is even possible and I received very favorable opinions which lead me to believe that from a sql perspective it is possible.

http://forums.oracle.com/forums/thread.jspa?threadID=510229

So, does anyone know how to do this in a Hibernate criteria object? The reason why I want to know is that the cost of the query is rather expensive (triple join) and we want to minimize a performance hit with two sql statements for the same info - one to get the page of data and one to get the total available.

Anyone know how to do this?

Thanks in advance,
Mark


Top
 Profile  
 
 Post subject: Pagination + rowcount()
PostPosted: Mon Jul 28, 2008 1:03 pm 
Newbie

Joined: Mon Jul 28, 2008 12:55 pm
Posts: 3
I have the same problem.

Did you find a solution to this issue?

Thanks in advance.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jul 28, 2008 2:55 pm 
Regular
Regular

Joined: Sat Jan 22, 2005 6:57 pm
Posts: 50
Location: Chicago
Unfortunately, no.

I ended up just splitting it into two separate sql statements like so:

Code:
Criteria criteria = ....
criteria.setProjection(Projections.rowCount());
Integer totalCount = criteria.uniqueResult();

// wipe out the projection, keep the criteria
criteria.setProjection(null);   

// add the pagination stuff
criteria.setMaxResults(PAGE_SIZE);
criteria.setFirstResult(PAGE_SIZE * pageNumber);

// results for the page
List results = criteria.list();


Top
 Profile  
 
 Post subject:
PostPosted: Fri Oct 31, 2008 12:46 pm 
Newbie

Joined: Fri Oct 31, 2008 12:21 pm
Posts: 4
This thread is a bit old, but I'm using this same technique for automatically paging Criteria queries and ran into a problem. If the passed criteria has already a projection, this technique overwrites the original criteria when it sets the the projection to null. To avoid this situation, what I did is to save the original Projection and ResultTransformer, seting the count projection and then restoring the original Projection and ResultTransformer like this:


Code:
    // Cast to CriteriaImpl to get access to the Projection and ResultTransformer
    CriteriaImpl cImpl = (CriteriaImpl) aCriteria;

    // Save original Projection and ResultTransformer (if any, could be null).
    Projection originalProjection = cImpl.getProjection();
    ResultTransformer originalResultTransformer = cImpl.getResultTransformer();

    // Get total count of elements by setting a count projection
    long totalElements = ((Integer) aCriteria.setProjection(Projections.rowCount())
            .uniqueResult()).longValue();

    // Restore original Projection and ResultTransformer
    aCriteria.setProjection(originalProjection);
    aCriteria.setResultTransformer(originalResultTransformer);

    // Paging stuff:
    aCriteria.setFirstResult(firstRecord).setMaxResults(pageSize).list();


The ResultTransformer has to be saved and then restored, because setting the count projection also changes the original ResultTransformer.

This is working for me, but I would like to know if there is a better/cleaner way of doing this (i.e. without modifying the original criteria).
I'm also not 100% sure that restoring the original Projection and ResultTransformer is all that is needed to return the criteria to its original state.

Any feedback would be greatly welcomed.

P.S. Using Hibernate 3.2.6


Top
 Profile  
 
 Post subject: Re: Pagination with Projection.rowCount() in a single call?
PostPosted: Fri Aug 03, 2012 10:14 am 
Newbie

Joined: Wed Sep 28, 2011 7:12 am
Posts: 4
Hi.

For now I found two solutions:
1. save Projection and ResultTransformer before getting rows, and then restore it
2. use second criteria to get count of rows

About first solution: I'm not sure that restoring Projection and ResultTransformer only needed to get original criteria state
Is it some better solution to get count of rows from criteria and use criteria later?

This feature is very usable for pagination: get number of all results and then set restrictions for the current page number and page size.
In JIRA I've found feature request, but it still not implemented: https://hibernate.onjira.com/browse/HHH-1046


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

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:
cron
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.