-->
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.  [ 4 posts ] 
Author Message
 Post subject: Undoing a setProjection(). Should it be like this?
PostPosted: Thu May 18, 2006 10:18 pm 
Newbie

Joined: Tue May 16, 2006 4:26 pm
Posts: 5
I am using the fancy new projection to get a count of rows, and then I want to re-run the same criteria as a list. This is just a simple pager.

It generally goes like this :
Code:
Criteria crit = getSession().createCriteria(getPersistentClass());
.. add critiera objects
crit.setProjection(Projections.rowCount());
return (Integer) crit.uniqueResult();


This leaves the critiera in a permanant 'projection' state, which I need to get out of.
The base Critieria interface has no methods for getProjection/getResultTransformer, only to set them, but the CritieraImpl itself does.

So this is what I do to get around this, which is basically just cast, save old values, and then re-set:
Code:
Long countByCriteria(Criteria crit ) {
        ResultTransformer oldRes  = ((CriteriaImpl) crit).getResultTransformer();
        Projection        oldProj = ((CriteriaImpl) crit).getProjection();
        crit.setProjection(Projections.rowCount());
        Long out = ((Integer) crit.uniqueResult()).longValue();
        crit.setProjection(oldProj);
        crit.setResultTransformer(oldRes);
        return out;
}


Is this an oversight that will be changed, or is there a reason for this? There is no way for me to poke at projectionCritieria ( which is just set to 'this') so I'm not sure I'm not leaving something in a bad state.

Thanks,
Andrew Backer


Top
 Profile  
 
 Post subject:
PostPosted: Thu May 18, 2006 11:23 pm 
Expert
Expert

Joined: Thu Dec 23, 2004 9:08 pm
Posts: 2008
I can't think of a good reason to get a Criteria's current projection. I'm pretty sure that you don't need to use a projection for what you're doing: just use the criteria in the normal way, and use the size() method on the returned list. That way you only have to go to the DB once, to get the actual result set.

Note that you can use setProjection(null) if you want to undo the rowCount thing.

_________________
Code tags are your friend. Know them and use them.


Top
 Profile  
 
 Post subject:
PostPosted: Fri May 19, 2006 3:38 pm 
Newbie

Joined: Tue May 16, 2006 4:26 pm
Posts: 5
Not sure if that is a good idea. This is a list (potentially) of hundreds of thousands of records, so I don't see how it could be a good idea to return every record in the table just to count the size of this query. Were I coding this by hand I would not (nor would anyone else) think of pulling down a record set of huge size to call rs.last(); rs.getRowNumber().

I thought this was the case this was introduced for. I am new, but I recall talk of people writing custom hql solutions just to get the rowcounts, and that some other custom solutions should be bypassed because HB3 was going to move towards this idea of projections.

Myself, I can't think of a good reason to get the projection either. Well, there is no good reason if you are able to reset it. Since you *can't* reset the properties that setProjection() modified (the point of the post) you need to do it this way so you can preserve/reset them after.

I use the same critiera for count & listing. If I do not do this I make two copies (identically constructed) of a critiera and then call count on one and list on the other.

To be more explicit, here is the use case :
1. Construct complex criteria
2. call countResults()
3. set max results, first record # (for offset/limit)
4. call list()
... viola, a simple recordset pager that only retrieves one page of data at a time.

So, what I am doing actually does _work_, but I am not sure this is the way it was intended to be. Is the fact that you can't un-set a projection an oversight, or is there some super easy way to clone criteria so that I don't have to do the creation process twice.

- Andrew


Top
 Profile  
 
 Post subject:
PostPosted: Sun May 21, 2006 5:36 pm 
Expert
Expert

Joined: Thu Dec 23, 2004 9:08 pm
Posts: 2008
You can reset/unset the project: criteria.setProjection(null) works just fine. Note that you have to set the result transformer afterwards, because just calling setProjection, even setProjection(null), changes the result transformer to PROJECTION. You probably want to set it to ROOT_ENTITY or DISTINCT_ROOT_ENTITY.

_________________
Code tags are your friend. Know them and use them.


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