4.10. Large Result Sets

By default, Kodo uses standard forward-only JDBC result sets, and completely instantiates the results of queries on execution. When using a JDBC driver that supports version 2.0 or higher of the JDBC specification, however, you can configure Kodo to use scrolling result sets that may not bring all results into memory at once. You can also configure the number of result objects Kodo keeps references to, so that you can traverse potentially enormous amounts of data without exhausting JVM memory. On-demand loading is also applied to extent iterators, and can be configured for individual collection and map fields via large result set proxies .

To configure Kodo's handling of result sets, use the following properties:

Example 4.11. Specifying Result Set Defaults

kodo.FetchBatchSize: 20
kodo.jdbc.ResultSetType: scroll-insensitive
kodo.jdbc.FetchDirection: forward
kodo.jdbc.LRSSize: last

Many Kodo JDO runtime components such as the KodoPersistenceManager, KodoQuery, and KodoExtent also have methods to configure these properties on a case-by-case basis through their fetch configuration object.

Example 4.12. Specifying Result Set Behavior at Runtime

import java.sql.*;
import kodo.query.*;
import kodo.jdbc.runtime.*;


KodoQuery kq = (KodoQuery) pm.newQuery (MyClass.class, "foo == bar");
JDBCFetchConfiguration fetch = (JDBCFetchConfiguration) 
    kq.getFetchConfiguration ();
fetch.setFetchBatchSize (20);
fetch.setResultSetType (ResultSet.TYPE_SCROLL_INSENSITIVE);
fetch.setFetchDirection (ResultSet.FETCH_FORWARD);
fetch.setLRSSize (JDBCFetchConfiguration.SIZE_LAST);
Collection results = (Collection) kq.execute ();

To facilitate users who require random access to query results, Kodo JDO always returns an implementation of java.util.List from calls to Query.execute. Remember, though, that other JDO implementations might choose to only implement the java.util.Collection interface in their query result objects. Also, note that unless ordering is specified in your query, there is no guarantee that multiple executions of the same query will return their results in the same order.

Example 4.13. Using Random Access Query Results in a Portable Fashion

// we want to ensure that we always order the results in the same way
Query query = pm.newQuery (Product.class, "productName == 'Stereo'");
query.setOrdering ("productCode ascending");

Collection results = (Collection) query.execute ();
List resultList;
if (results instanceof List)      // always the case with Kodo JDO
    resultList = (List) results;
    // portable, but it will wind up instantiating all elements in
    // collection, which might be a huge number of objects
    resultList = new ArrayList (results);

// get start and end indexes of results to display from web request
int start = Integer.parseInt (jspRequest.getParameter ("start"));
int end = Integer.parseInt (jspRequest.getParameter ("end"));

// print info about each product in list range from "start" to "end"
for (int i = start; i < end && i < resultList.size (); i++)
    out.print ("Stereo #" + i + ": "
        + ((Product) resultList.get (i)).getDescription ());

query.close (results);