Showing posts with label ORM. Show all posts
Showing posts with label ORM. Show all posts

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

Thursday, July 29, 2010

The eagerness of JPA

JPA came to life as a result of JSR 220. This request originated to provide a uniform API and way of working across different ORM solutions such as Hibernate, Toplink and JDO. One member of the expert group leading JSR 220 was righteously Gavin King, the main inventor of Hibernate. Since Hibernate is the most widely used implementation, I thougth they would follow most of its important design decisions. For instance in hibernate the default fetching strategy is 'lazy'. Although this can sometimes lead to difficulties with casts and object equality (if you received a proxy in stead of the real object), it has as advantage that you only fetch dependencies in memory when you need them. I was suprised to see that in JPA the default fetch of a @manyToOne for instance is 'eager'?!

This lead to the fact that someone in my team unwillingly dragged half the DB in memory :) If anybody knows why they decided to change this, please let me know. Thx