-->
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.  [ 12 posts ] 
Author Message
 Post subject: Getting total number of rows returned without setMaxResults
PostPosted: Thu Dec 15, 2005 5:10 pm 
Newbie

Joined: Thu Dec 15, 2005 2:30 pm
Posts: 10
Is there a clean way to determine number of rows that WOULD have been returned if setMaxResults was not specified? Along the lines of MySQL's "SELECT SQL_CALC_FOUND_ROWS ..." and "SELECT FOUND_ROWS()". Obviously, I need this to allow for pretty pagination through a large list of items. Regards!


Top
 Profile  
 
 Post subject:
PostPosted: Thu Dec 15, 2005 6:49 pm 
Expert
Expert

Joined: Sat Jun 12, 2004 4:49 pm
Posts: 915
i do ScrollableResult and do it like this :
ScrollableResults scr = query.scroll();
src.last();
int size = scr.getRowNumber();


see faq example for another way


Top
 Profile  
 
 Post subject:
PostPosted: Mon Dec 19, 2005 1:30 pm 
Newbie

Joined: Thu Dec 15, 2005 2:30 pm
Posts: 10
Wouldn't scroll() load all of the data and be just as slow as loading it all explicitly anyways?

Ans what "other" way in the FAQ are you referring to? Using "select count(*) ..."? I figured I could do that, but I was also wondering if hibernate had some sort of a framework for paging through collections of items.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Dec 19, 2005 8:57 pm 
Expert
Expert

Joined: Sat Jun 12, 2004 4:49 pm
Posts: 915
Quote:
Wouldn't scroll() load all of the data and be just as slow as loading it all explicitly anyways?

no, scroll make cursor only - i play with about 200000 rows and it work fine
scroll.last() is longer and it populate last row -
"select count(*) can be better (maybe), but you have to make to queries (one for count and
other for true query)
i prefer scroll/last combination


Top
 Profile  
 
 Post subject:
PostPosted: Tue Dec 20, 2005 3:03 am 
Newbie

Joined: Thu Dec 15, 2005 2:30 pm
Posts: 10
snpesnpe, thank you for the helpful response. I will definitely play with the scroll() idea!


Top
 Profile  
 
 Post subject:
PostPosted: Tue Dec 20, 2005 7:25 am 
Newbie

Joined: Fri Nov 04, 2005 4:47 am
Posts: 14
I use MySQL, and the scroll solution is a very bad idea on MySQL, I found that it was very slow. There is a much cleaner and more elegant approach, use a projection:

Code:
   
    criteria.setProjection(Projections.rowCount());
    Integer count = (Integer) criteria.uniqueResult();
    itemCount = count.intValue();
    criteria.setProjection(null);
    criteria.setResultTransformer(Criteria.ROOT_ENTITY);


Notice the setProjection(null) and setResultTransformer which set the criteria query back to how it was.

(I do this before I set the max results).

This of course only works if you use the Criteria API, but I find that this API is quite useful for the typical cases where I need pagination anyway.[/code]

When I tested this solution against the scrolling solution (on mysql, which doesn't have cursors), I found that the scroll solution used the same amount of time as when I simply called list(), i.e. queried for all matching projects. The rowCount solution given here simply executes a COUNT(*) so it's much faster.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Dec 20, 2005 2:08 pm 
Newbie

Joined: Thu Dec 15, 2005 2:30 pm
Posts: 10
Projections.rowCount() sure did the trick. Thanks. What a beautiful solution!


Top
 Profile  
 
 Post subject:
PostPosted: Tue Dec 20, 2005 6:09 pm 
Expert
Expert

Joined: Sat Jun 12, 2004 4:49 pm
Posts: 915
scroll is slow on non-cursor oriented databases like mysql
this databases load complete query (for every query) in memory and it work very bad
for large databases - you can't do 'select * from table_name' for big table - you get
'out of memory' - postgresql is non-cursor, too, but it have hack for cursors in newer versions
i know that oracle work perfect for big tables - you call 'select * from table_name' and
database load X rows (fetchSize in java, but it is same for every client) - you can see
first Y rows (walk cursor) and see what you interest (all rows are never in memory in one moment)

non-cursor database do hack for this cases with limit clause, but it isn't sql keyword and it is unnecessary for true cursor's database


Top
 Profile  
 
 Post subject:
PostPosted: Sat Jan 21, 2006 3:00 pm 
Newbie

Joined: Tue Nov 15, 2005 2:14 am
Posts: 7
Are there a way to read the current database name through hibernate API?
It would be usefull for this use case :
if (mysql)
count;
else scroll;

or to read a property telling if the database support scrolling through cursor?


Top
 Profile  
 
 Post subject:
PostPosted: Sat Jan 21, 2006 3:22 pm 
Expert
Expert

Joined: Sat Jun 12, 2004 4:49 pm
Posts: 915
this is one possibility :

configuration.getProperty(Environment.DIALECT).equals("org.hibernate.dialect.MySQLDialect")

you remember configuration in HibernateUtil


Top
 Profile  
 
 Post subject: Hibernate Criteria should provide paging functionality
PostPosted: Wed Mar 18, 2009 1:18 pm 
Beginner
Beginner

Joined: Tue Nov 06, 2007 5:13 am
Posts: 28
andnaess wrote:
I use MySQL, and the scroll solution is a very bad idea on MySQL, I found that it was very slow. There is a much cleaner and more elegant approach, use a projection:

Code:
   
    criteria.setProjection(Projections.rowCount());
    Integer count = (Integer) criteria.uniqueResult();
    itemCount = count.intValue();
    criteria.setProjection(null);
    criteria.setResultTransformer(Criteria.ROOT_ENTITY);



unfortunately this does not work, if the criteria uses order by statements (at least not on my postgres-database), because hibernate will create a query like this:
Code:
select count(*)
from table
order by field

which will cause an sql-exception.

to work around this I use a nasty hack. Where I must cast my criteria to CriteriaImpl fro iterateOrderings.
Then I remove all of them, execute the count and reapply the ordering before executing the list().

I really wished Hibernate would provide a paging functionality - then the HibernateDialect could use the most appropriate way for each database.


Top
 Profile  
 
 Post subject: Re: Getting total number of rows returned without setMaxResults
PostPosted: Mon Nov 29, 2010 12:24 pm 
Beginner
Beginner

Joined: Mon Nov 13, 2006 8:22 am
Posts: 28
Another solution is the following:
1. run your criteria.list() without setting any alias => the referenced sets/list of the root entity will be filled with proxies => here you set correctly the max results and such
2. run the alias criteria on its own in the same hibernate session => the above proxies will be initialized

something like this:

Code:
    Criteria criteria = this.getSession().createCriteria(User.class);
    criteria.setResultTransformer(CriteriaSpecification.ROOT_ENTITY);
    criteria.setMaxResults(10);

    // First get the results without joining with the other tables
    List<User> results = criteria.list();

    // at this point the set roles is filled with proxies
    // we'll now create and execute the join so these proxies are filled since we're still in the same session
    getSession().createCriteria(User.class, "u")
            .createAlias("u.roles", "r", CriteriaSpecification.LEFT_JOIN)
            .list();

    return results;


Hope this can help,
Stijn


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 12 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:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.