Chapter 12. FetchPlan

12.1. Detachment Options

The previous chapter showed you how to retrieve objects with JDO queries. But how do you control which fields and relations of those objects are fetched immediately, and which are loaded lazily? Similarly, when you use the PersistenceManager to lookup an object by JDO identity, or when you traverse a persistent relation, how does the JDO implementation decide which fields to populate? The answer lies in fetch groups.

Section 5.4, “Field Element” introduced the default fetch group. This is the metadata-defined set of fields that load by default whenever you retrieve an object. Section 5.5, “Fetch Group Element” showed you how to define additional custom fetch groups for additional control. By specifying the set of active fetch groups at runtime, you control the persistent fields that are populated immediately, versus those that are populated lazily. The interface you use to specify the set of active fetch groups is the FetchPlan.

PersistenceManager, Query, and Extent instances expose their fetch plans though their respective getFetchPlan methods.

public FetchPlan getFetchPlan ();

The PersistenceManager's plan dictates the set of active fetch groups used when loading objects by JDO identity, or when traversing persistent relations. When a new query is created through the PersistenceManager's newQuery or newNamedQuery methods, the query inherits the fetch plan settings from the PersistenceManager.

As you expect, Query and Extent plans apply to the objects loaded through the execution of the query or iteration of the extent. You can modify a Query or Extent's fetch plan independently of the owning PersistenceManager's plan; changes to one do not affect the other.


Kodo extends the standard FetchPlan interface with the KodoFetchPlan interface and its relational sub-interface, the JDBCFetchPlan. Section 9.3.7, “KodoFetchPlan” of the Reference Guide details these interfaces.

public static final String DEFAULT = "default";
public Collection getGroups ();
public FetchPlan addGroup (String group);
public FetchPlan removeGroup (String group);
public FetchPlan setGroup (String group);
public FetchPlan setGroups (Collection groups);
public FetchPlan setGroups (String[] groups);

FetchPlan defines several methods for manipulating the set of active fetch groups, and a single getGroups accessor to retrieve an immutable view of the set. Each mutator returns a reference to the FetchPlan instance for method chaining.

The DEFAULT constant represents the default fetch group.

public static int FETCH_SIZE_GREEDY = -1;
public static int FETCH_SIZE_OPTIMAL = 0;
public int getFetchSize ();
public FetchPlan setFetchSize (int size);

The fetch size is a hint to the implementation on how to process result sets. FETCH_SIZE_GREEDY eagerly loads all result objects. FETCH_SIZE_OPTIMAL leaves the result set processing strategy up to the JDO implementation. And any positive number N instructs the JDO runtime to process results as you access them in batches of N.


Kodo excels at large result set handling. Under the proper settings, Kodo can even process result sets consisting of more objects than can fit into JVM memory.

Example 12.1. Using the FetchPlan

PersistenceManager pm = ...;
Query query = pm.newQuery (Magazine.class, " == 'Random House'");
query.getFetchPlan ().setFetchSize (50).addGroup ("search-results");
List mags = (List) query.execute ();
for (Iterator itr = mags.iterator (); itr.hasNext ();)
    processMagazine ((Magazine) ());

12.1. Detachment Options

In addition to controlling the active fetch groups, the fetch plan allows you to control the PersistenceManager's detach behavior. We covered detachment in Section 8.7, “Detach and Attach Functionality”.

public static int DETACH_LOAD_FIELDS;
public static int DETACH_UNLOAD_FIELDS;
public int getDetachmentOptions (); 
public void setDetachmentOptions (int flags);

The bit flags above control what state is available in your detached objects. By default (flags = 0), the set of fields available in a detached instance is determined is the set of fields that were loaded when the original object was detached. The DETACH_LOAD_FIELDS flag instructs the JDO implementation to load the fields in your active fetch groups before detaching, guaranteeing that these fields will be available in the detached instance. The DETACH_UNLOAD_FIELDS flag, on the other hand, ensures that fields outside of your active fetch groups will not be available in the detached instance, even if they were loaded in the original managed object. You can combine these flags using bitwise operators.

Example 12.2. Using Detachment Options

PersistenceManager pm = ...;
pm.getFetchPlan ().setDetachmentOptions (FetchPlan.DETACH_LOAD_FIELDS

Kodo's extended kodo.jdo.KodoFetchPlan also includes a DETACH_ALL_FIELDS flag.

Kodo currently does not support the DETACH_LOAD_FIELDS flag unless you also set the DETACH_UNLOAD_FIELDS flag, as in the example above.