Chapter 12. FetchPlan
Prev | Part 3. Java Data Objects | Next

## Chapter 12. FetchPlan

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.

| Note
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`.

| Note
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, "publisher.name == 'Random House'");
    query.getFetchPlan ().setFetchSize (50).addGroup ("search-results");
    List mags = (List) query.execute ();
    for (Iterator itr = mags.iterator (); itr.hasNext ();)
        processMagazine ((Magazine) itr.next ());

## 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
        | FetchPlan.DETACH_UNLOAD_FIELDS);

| Note
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.

Prev | Up | Next
11.12. Conclusion | Home | Chapter 13. DataStoreCache