-->
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.  [ 7 posts ] 
Author Message
 Post subject: Request: Scrollable results with criteria query
PostPosted: Wed Dec 17, 2003 2:44 am 
Expert
Expert

Joined: Fri Nov 07, 2003 4:24 am
Posts: 315
Location: Cape Town, South Africa
What is the possibility of the following functionality:
Code:
Criteria crit = Session.createCriteria(Foo.class);
crit.add(....)
....
ScrollableResults scroller = crit.scroll();


Regards

Justin


Top
 Profile  
 
 Post subject:
PostPosted: Wed Dec 17, 2003 2:56 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
What do you use it for?


Top
 Profile  
 
 Post subject:
PostPosted: Wed Dec 17, 2003 3:26 am 
Expert
Expert

Joined: Fri Nov 07, 2003 4:24 am
Posts: 315
Location: Cape Town, South Africa
I have several queries which are used to display results in a web page. My original code used the criteria API to formulate these queries:
Code:

Criteria crit = session.createCriteria(Learner.class);
if (learnerCriteria.getFirstNames() != null) {
    crit.add(Expression.ilike("firstNames", learnerCriteria.getFirstNames(), MatchMode.START));
}
if (learnerCriteria.getSurname() != null) {
    crit.add(Expression.ilike("surname", learnerCriteria.getSurname(), MatchMode.START));   
}
if (learnerCriteria.getUserName() != null) {
    crit.add(Expression.ilike("userName", learnerCriteria.getUserName(), MatchMode.START));
}


All the results where displayed on a single page.

With the increase in the number of learners, a request was made to display these results in a scrollable manner (page-by-page), with a customizable range size, hyperlinks to other offsets and a display of the total number of results. To implement this I used the Query interface, calling scroll() as follows:
Code:
StringBuffer sql = new StringBuffer(300);
sql.append("FROM Learner l WHERE 1=1 ");            
if (learnerCriteria.getFirstNames() != null) {
   sql.append("WHERE UPPER(l.firstNames) like :firstNames ");
}
if (learnerCriteria.getSurname() != null) {
   sql.append("WHERE UPPER(l.surname) like :surname ");   
}
if (learnerCriteria.getUserName() != null) {
   sql.append("WHERE UPPER(l.userName) like :userName ");
}
sql.append("ORDER by l.userName ");

// bind parameters
Query query = session.createQuery(sql.toString());
if (learnerCriteria.getFirstNames() != null) {
   query.setString("firstNames", learnerCriteria.getFirstNames().toUpperCase() + "%");
}
if (learnerCriteria.getSurname() != null) {
   query.setString("surname", learnerCriteria.getSurname().toUpperCase() + "%");   
}
if (learnerCriteria.getUserName() != null) {
   query.setString("userName", learnerCriteria.getUserName().toUpperCase() + "%");
}

ScrollableResults scroller = query.scroll();
RangedQueryResult rangedResult = new RangedQueryResult();
rangedResult.setRangeSize(rangeSize);

// set up the ranged result
if (scroller.last()) {
   rangedResult.setTotalSize(scroller.getRowNumber());
   rangedResult.setRangeOffSet(offSet);
   if (offSet <= 0) {
      scroller.beforeFirst();
   } else {
      scroller.scroll(offSet);
   }
} else {
   rangedResult.setTotalSize(0);
   rangedResult.setItems(Collections.EMPTY_LIST);
   rangedResult.setRangeOffSet(0);
   return rangedResult;               
}

// populate the selected contents
List results = new ArrayList();            
int count = 1;

while (scroller.next() && (count < rangeSize)) {
   results.add(scroller.get()[0]);
   count++;
}

rangedResult.setItems(results);
return rangedResult;


where RangedQueryResult is the following:

Code:
public class RangedQueryResult implements Serializable {
   
   private List items; // the actual items selected to display (may be less than rangeSize)
   private int rangeSize; // the maximum size of the items in the items list
   private int rangeOffSet; // the offset at which the subset of items starts in the greater scheme of things
   private int totalSize; // the total size of the results returned by the query
//... getters and setters
}


As you can imaging, I would have preferred to just have called criterial.scroll()

(Note - I haven't run/tested the new code yet)

Justin


Top
 Profile  
 
 Post subject:
PostPosted: Wed Dec 17, 2003 4:33 am 
Isn't it better to use setFirstResult()/setMaxResults() for pagination?


Top
  
 
 Post subject:
PostPosted: Wed Dec 17, 2003 4:46 am 
Expert
Expert

Joined: Fri Nov 07, 2003 4:24 am
Posts: 315
Location: Cape Town, South Africa
Quote:
Isn't it better to use setFirstResult()/setMaxResults() for pagination?


AFAIK that only allows you to scroll foward and limits the number of results returned by list(). I need to accurately count the number of rows (to build an index) whilst executing a (criteria) query.

My request was fueled by the fact that I had to do a large amount of refactoring of code (change from clean criteria query to more verbose normal query) just to allow scrolling backward and forward in a result set.

BTW: The corrected/debugged code that works is the following

Code:
StringBuffer sql = new StringBuffer(300);
sql.append("FROM Learner l WHERE 1=1 ");            
if (learnerCriteria.getFirstNames() != null) {
   sql.append("AND UPPER(l.firstNames) like :firstNames ");
}
if (learnerCriteria.getSurname() != null) {
   sql.append("AND UPPER(l.surname) like :surname ");   
}
if (learnerCriteria.getUserName() != null) {
   sql.append("AND UPPER(l.userName) like :userName ");
}
sql.append("ORDER by l.userName ");

// bind parameters
Query query = session.createQuery(sql.toString());
if (learnerCriteria.getFirstNames() != null) {
   query.setString("firstNames", learnerCriteria.getFirstNames().toUpperCase() + "%");
}
if (learnerCriteria.getSurname() != null) {
   query.setString("surname", learnerCriteria.getSurname().toUpperCase() + "%");   
}
if (learnerCriteria.getUserName() != null) {
   query.setString("userName", learnerCriteria.getUserName().toUpperCase() + "%");
}

ScrollableResults scroller = query.scroll();
RangedQueryResult rangedResult = new RangedQueryResult();
rangedResult.setRangeSize(rangeSize);

// set up the ranged result
if (scroller.last()) {
   int rows = scroller.getRowNumber() + 1;
   rangedResult.setTotalSize(rows);
   rangedResult.setRangeOffSet(offSet);
   if (offSet <= 0) {
      scroller.beforeFirst();
   } else {
      if (!scroller.setRowNumber(offSet - 1)) {
         scroller.beforeFirst();
         rangedResult.setRangeOffSet(0);
      }
   }
   
} else { // no results
   rangedResult.setItems(Collections.EMPTY_LIST);
   rangedResult.setRangeOffSet(0);
   return rangedResult;               
}

// populate the selected contents
List results = new ArrayList();            
int count = 0;

while (scroller.next() && (count < rangeSize)) {
   results.add(scroller.get()[0]);
   count++;
}

rangedResult.setItems(results);
return rangedResult;


Top
 Profile  
 
 Post subject: Criteria.scroll() could be used for large result sets.
PostPosted: Thu Dec 18, 2003 5:15 pm 
Newbie

Joined: Thu Dec 18, 2003 3:20 pm
Posts: 6
I'd like to leverage this features to scroll through large results without having to load a List into memory.

Using the scroll feature I could only return one loaded object at a time, process it, get the next.


Top
 Profile  
 
 Post subject: Re: Criteria.scroll() could be used for large result sets.
PostPosted: Tue Mar 16, 2004 6:53 am 
Newbie

Joined: Mon Mar 08, 2004 3:59 am
Posts: 2
dtdeluca wrote:
I'd like to leverage this features to scroll through large results without having to load a List into memory.

Using the scroll feature I could only return one loaded object at a time, process it, get the next.



Sorry...

You mean that using scroll feature is better than loading a List at a time.

How about using "setMaxResults" and "setFirstResult" ?

Is it better than scroll ?


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