Sunday, September 12, 2010

Can you fetch me this thingie? Just for me please...

Kodo is a JDO implementation that it's not widely adopted and a bit more complex than Hibernate. Neverteless I found at least feature that it already had long before Hibernate did, called 'fetch groups'. With a fetch group you can for instance eager fetch a collection that is defaulty mapped as lazy for a certain scenario.

Let's say a bunch of addresses are defaulty mapped 'lazy' to a customer. We can then define a fetch group (eg 'addressFetchGroup') to indicate that this collection should be eagerly fetched when this group id is used in the query.

Here's what this would look like:

The package.jdo (mapping) file:

<class name="Customer">
<extension vendor-name="kodo" key="data-cache" value="false" />
<extension vendor-name="kodo" key="jdbc-sequence-factory" value="native" />
<extension vendor-name="kodo" key="jdbc-sequence-name" value="MYSEQUENCE" />
<field name="name" persistence-modifier="persistent" />

<field name="addresses" default-fetch-group="false">
<collection element-type="address" />
<extension vendor-name="kodo" key="fetch-group" value="addressFetchGroup"/>
</field>

...

The code:

public Customer lookUpCustomerWithAddresses(String customerId) {

Collection fetchGroups = new ArrayList();
fetchGroups.add("addressFetchGroup");
fetchGroups.add("otherFetchGroup");
...
return retrieveWithFetchGroups(fetchGroups, customerId);
}

@SuppressWarnings("unchecked")
public <S> Collection<S> retrieveWithFetchGroups(Collection<String> fetchGroups, Object... parameters) {
KodoQuery query = (KodoQuery) persistenceManager.newJDOQuery();
try {
query.getFetchConfiguration().addFetchGroups(fetchGroups);
return (Collection) query.executeWithArray(parameters);
} catch (Exception ex) {
...
}
}

When used correctly (and more importantly, measured correctly with a profiler), this can greatly improve performance of a specific use case, without affecting other use cases. As of hibernate 3.5 this feature is also included and known as 'fetch profiles'.