-->
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: Using the Criteria API to order results by collection size?
PostPosted: Mon Dec 11, 2006 1:40 pm 
Newbie

Joined: Fri Dec 08, 2006 6:54 pm
Posts: 3
Hi, hopefully this is a straightforward question.

I'd like to order a set of query results by the size of a collection property. The FAQ tells me how to do this in HQL, but is there a way to do it using the Criteria API? For example, using the following schema:

class User
- Set<Message> messages; // one-to-many relation

... I'd like to do something similar to the following:

Code:

Criteria c = session.createCriteria(User.class);

/* ... add other constraints ... */

c.addOrder(Order.asc("messages.size")); // doesn't work, of course


Is there something I'm missing?

Thanks!


Top
 Profile  
 
 Post subject:
PostPosted: Mon Dec 11, 2006 2:02 pm 
Expert
Expert

Joined: Tue Jul 11, 2006 10:21 am
Posts: 457
Location: Columbus, Ohio
Maybe this:

Code:
List results = session.createCriteria(User.class)
  .createCriteria("messages").
  .setProjection( Projections.rowCount(), "countByUser")
  .addOrder( Order.asc("countByUser")
  .list();


Top
 Profile  
 
 Post subject:
PostPosted: Mon Dec 11, 2006 3:11 pm 
Newbie

Joined: Fri Dec 08, 2006 6:54 pm
Posts: 3
Ananasi wrote:
Maybe this:

Code:
List results = session.createCriteria(User.class)
  .createCriteria("messages").
  .setProjection( Projections.rowCount(), "countByUser")
  .addOrder( Order.asc("countByUser")
  .list();


Sadly, that doesn't seem to quite work.

I tried something similar to this:

Code:
List results = session.createCriteria(User.class)
  .createCriteria("messages").
  .setProjection( Projections.alias(Projections.rowCount(), "countByUser"))
  .addOrder( Order.asc("countByUser"))
  .list();


... and that returns a nicely ordered list of the message counts, but not the users. I even tried splitting the invocation and calling list() on the original criteria instance (created with Session.createCriteria()) but that seems to have identical behavior.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Dec 12, 2006 5:07 pm 
Newbie

Joined: Fri Dec 08, 2006 6:54 pm
Posts: 3
For those interested, it turned out that there was no good solution to this. Even hand-building queries via HQL was extremely painful, since in order to reconstitute the list of returned objects I had to enumerate all of the attributes of the object and its ancestors in the select statement. And then even that broke, since it didn't properly order "Users" without any "messages".

I wound up just adding a derived property (e.g. "msgCount") to the object definition that represented the thing that I wanted to order by, and inserted a formula that consisted of a blob of SQL that calculated the property, e.g.

Code:
       
<joined-subclass name="com.example.User" table="user">
     <property name="msgCount" lazy="true" formula="COALESCE((SELECT COUNT(msg.user_id) FROM Message msg WHERE msg.user_id = id GROUP BY msg.user_id), 0)"/>
</joined-subclass>


The "msgCount" property can then be referenced like any other property in the Criteria API. This is probably not the most efficient solution, but it seems to work.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Sep 27, 2007 4:20 pm 
Newbie

Joined: Thu Sep 27, 2007 4:12 pm
Posts: 1
So, adding a @Formula is the only solution?

I would love to do this:

criteria.addOrder(Property.forName("size(widgets)").desc()

OR

criteria.addOrder(Property.forName("widgets.size").desc()

(of course, neither works)


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