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.


Recommended Articles

Mastering JPA Criteria API for Efficient and Maintainable Data Retrieval

Discover how to use the JPA Criteria API for efficient data retrieval in Java applications. Learn about its benefits, syntax, and usage with examples.

Optimizing Data Pagination in Enterprise Java Applications

Enhance your enterprise applications' data handling with efficient pagination techniques using WildFly 31 and Java 21.

Dynamic Data Filtering with Criteria API and Data Filters in Enterprise Java Applications

Enhance your enterprise Java applications with dynamic data filtering using Criteria API and Data Filters. Learn how to create, apply, and parametrize filters for flexible conditions.

Master Jakarta Persistence API (JPA) for CRUD Operations with Java

Learn how to use JPA for creating, reading, updating and deleting data using Java. Start your project with Maven archetype.