When an object is retrieved from the datastore by JPA typically not all fields are retrieved
immediately. This is because for efficiency purposes only particular field types are retrieved in the
initial access of the object, and then any other objects are retrieved when accessed (lazy loading).
The group of fields that are loaded is called a
fetch group
.
There are 2 types of "fetch groups" to consider
JPA provides an initial fetch group, comprising the fields that will be retrieved when an object
is retrieved if the user does nothing to define the required behaviour. You define this "default"
by setting the
fetch
attribute in metadata for each field/property.
As mentioned above, JDO allows specification of users own fetch groups (for enabling at particular
times) and DataNucleus makes that flexibility available for JPA via annotations.
For example, if we have the following class
class MyClass
{
String name;
HashSet coll;
MyOtherClass other;
}
and we want to have the
other
field loaded whenever we load objects of this class, we define
our annotations as
@PersistenceCapable
@FetchGroup(name="otherfield", members={@FetchMember("other")})
public class MyClass
{
...
}
So we have defined a fetch group called "otherfield" that just includes the field with name
other
. We can then use this at runtime in our persistence code.
EntityManagerImpl dnEM = (EntityManagerImpl)em;
dnEM.getFetchPlan().addGroup("otherfield");
... (load MyClass object)
By default the
FetchPlan
will include the default fetch group. We have changed this above by
adding
the fetch group "otherfield", so when we retrieve an object using this
EntityManager
we will be retrieving the fields
name
AND
other
since they
are both in the current
FetchPlan
. We can take the above much further than what is shown by
defining nested fetch groups in the MetaData. In addition we can change the
FetchPlan
just
before any
PersistenceManager
operation to control what is fetched during that operation.
The user has full flexibility to add many groups to the current
Fetch Plan
.
This gives much power and control over what will be loaded and when. A big improvement over
standard JPA!
The
FetchPlan
applies not just to calls to
EntityManager.find()
, but also
to
EntityManager.createQuery()
, as well as detaching.