How to use ScrollableResults with Hibernate

Supposing you have to fetch a large resultset and update the single objects. By using the standard Query Object you would retrieve the whole set of Objects in Memory:
Query q = session.createQuery("from ABC");
List l = q.list();
On the other hand, if you need to operate on an online cursor, then you can use the ScrollableResults in your Query as you can see in this example:
public class ScrollableResultsWithQuery {
    public static void main(String[] args) {
        Session session = HibernateUtil.getSessionFactory().openSession();
        ScrollableResults scResults = session.createQuery("from Customer")
               .scroll(ScrollMode.SCROLL_INSENSITIVE);
        while(scResults.next()) {
            Customer c = (Customer)scResults.get(0);
            System.out.println(g.getId()+", "+g.getName());
            scResults.afterLast();
        }
        session.close();
    }
}

ScrollableResults requires the underlying Hibernate API for the scrolling but you can use all the features of JPA querying. 

There are different modes available in ScrollableResults:

FORWARD_ONLY : It requests ScrollableResults that scrolls forward only.
SCROLL_SENSITIVE : ScrollableResults that is sensitive to changes in underlying data.
SCROLL_INSENSITIVE : Insensitive to changes in underlying data.

You are not restricted to using ScrollableResults with Query, you can use it also with the Criteria API:
public class ScrollableResultsWithCriteria {
    public static void main(String[] args) {
        Session session = HibernateUtil.getSessionFactory().openSession();
        ScrollableResults scResults = session.createCriteria(Customer.class)
                     .scroll(ScrollMode.FORWARD_ONLY);
        while(scResults.next()) {
            Customer c = (Customer)scResults.get(0);
            System.out.println(c.getId()+", "+c.getName());
        }
        //Set the location at index 2
        System.out.println("After setting location");
        scResults.setRowNumber(1);
        while(scResults.next()) {
            Customer c = (Customer)scResults.get(0);
            System.out.println(c.getId()+", "+c.getName());
        }
        session.close();
    }
}

Scrolling in JPA

There is no equivalent API in JPA to scroll through an open cursor. Still you can use as alternative the methods setMaxResult()/setFirstResult() as discussed in this tutorial: How to paginate your Entity data
Query query = em.createQuery("From Account");
query.setFirstResult(0);
query.setMaxResults(10);
List<Account> list = query.list();

In terms of performance, however, consider that using setMaxResult()/setFirstResult() will fire a new query every time, and the overhead really adds up. Plus, you need to sort on something for reliable paging which also adds to query times.

Found the article helpful? if so please follow us on Socials