-->
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.  [ 3 posts ] 
Author Message
 Post subject: count() on a collection
PostPosted: Fri Jun 04, 2004 8:02 pm 
Newbie

Joined: Fri Apr 02, 2004 2:22 pm
Posts: 11
Hi all,

I'm having some trouble figuring out just how to get a total record count using a query with parameters and joining multiple tables. I've been through the forum hoping to find a solution but I can't put it all together.

I'm currently running Hibernate 2.1.2 and MySQL 4.0.15

I have a somewhat complex query where I'm joining multiple tables via assocation tables. The part that needs some background is in the pet.attributes table. This is an association table of pets to their attributes and I'm selecting all pets who have match to three attributes (reference_id's).

An example of this association table might look like:

Code:
+--------+--------------+
| pet_id | reference_id |
+--------+--------------+
|      1 |            3 |
|      1 |          198 |
|      1 |          219 |
|      2 |            5 |
|      2 |           96 |
|      2 |          198 |
+--------+--------------+

My query is defined as

Code:
SELECT pet
  FROM Pet AS pet
    INNER JOIN pet.client AS cl
    INNER JOIN cl.clientToIdentity AS clid
    INNER JOIN pet.identity AS ident
    INNER JOIN pet.attributes AS rc
  WHERE rc.referenceId IN (198, 219, 3) AND
   LOWER(cl.accountId) LIKE LOWER(:accountId)AND
   clid.type=:clientType AND
   LOWER(clid.identity.firstname) LIKE LOWER(:ownerFirstName) AND
   LOWER(clid.identity.lastname) LIKE LOWER(:ownerLastName) AND
   ident.type=:petType AND
   LOWER(ident.identity.firstname) LIKE LOWER(:petFirstName) AND
   LOWER(ident.identity.lastname) LIKE LOWER(:petLastName)
  GROUP BY pet.petId
  HAVING COUNT(pet.petId)=3

and via hibernate I use

Code:
Query query = session.createQuery(querySearch);

query.setParameter("accountId", accountId+"%");
query.setParameter("clientType", "self");
query.setParameter("ownerFirstName", ownerFirstName+"%");
query.setParameter("ownerLastName", ownerLastName+"%");
query.setParameter("petType", "pet");
query.setParameter("petLastName", petLastName+"%");
query.setParameter("petFirstName", petFirstName+"%");
query.setFirstResult(nPageSize*nPageCount).setMaxResults(nPageSize);

return query.list();

Now the query returns the results as expected however, I want to know how many total records are in the result for paging purposes and I don't want to access that via

Code:
query.list().size()

since there could be a substantial number of records and the memory/performance hit would be way too costly.

I've tried using

Code:
int count = ((Integer)query.iterate().next()).intValue();

which returned a java.lang.ClassCastException, and

Code:
int count = ((Integer)session.createFilter(query, "select count(*)").iterate().next()).intValue())

which returned

Hibernate ExceptionThe collection was unreferenced
java.lang.NullPointerException


What am I missing?


Top
 Profile  
 
 Post subject:
PostPosted: Sat Jun 05, 2004 2:49 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 3:00 pm
Posts: 1816
Location: Austin, TX
You realize, that query.list() returns a fully loaded list, right? If you have the List already from query.list(), calling size() and that list is not gonna hardly any "memory/performance hit".

If you are talking about trying to get the count prior to calling query.list(), then thats a different issue (and if you are doing pagination you most likely want query.scrol() instead of query.list()).

Quote:
int count = ((Integer)query.iterate().next()).intValue();

You are querying for pets. Why would iterate() return an Integer?

Quote:
int count = ((Integer)session.createFilter(query, "select count(*)").iterate().next()).intValue())

createFilter() is used to narrow (filter) the results in an association collection http://www.hibernate.org/hib_docs/api/net/sf/hibernate/Session.html#createFilter(java.lang.Object,%20java.lang.String)

Unfortunately, the only way to do this currently is to either 1) do the list() and call its size; 2) perform an additional query selecting count(*) based on the same FROM and WHERE clauses.


Top
 Profile  
 
 Post subject:
PostPosted: Sat Jun 05, 2004 12:05 pm 
Newbie

Joined: Fri Apr 02, 2004 2:22 pm
Posts: 11
Steve,

Thanks for the response.

Yes I do realize that query.list() returns the actual list and I would like to know the size prior to doing that. I showed the code for that (and pagination) simply as an example of what I was doing. I don't want to load the entire list and then call size() because there could be 1000+ records, all of which I do not want to load into memory. I thought that perhaps hibernate had a way to take a query and then return a count based on the query but it sounds like an additional query that only returns the count is the way to go.

Again, many thanks for pointing out my ignorance and explaining things.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 3 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.