Jump to: navigation, search

EclipseLink/Development/Incubator/Extensions/NestedFetchGroup

< EclipseLink‎ | Development‎ | Incubator‎ | Extensions
Revision as of 15:33, 14 September 2009 by Douglas.clarke.oracle.com (Talk | contribs)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

Extensions Incubator: NestedFetchGroup

This page captures the requirements and design of Nested FetchGroup as per bug 273057. The goal is provide support for defining how an entire graph of objects is loaded giving the application developer fine grain control. A FetchGroup (org.eclipse.persistence.queries) currently allows a developer to specify which of the attributes in an entity class are populated when querying from the database. The functionality is limited to the scope of the traget entity of the query but can be created and used dynamically, pre-registered by name, or specified as the default for all queries and find operations.

The proposed enhancement will enable developers to define a hierarchy of nested FetchGroup instances to control the entire retrieval of an entity graph.

Requirements

  • Provide support for specifying multiple levels of FetchGroup behaviour for a query and use the created FetchGroup with either a JPA Query using a hint, on the native query, or register with a descriptor for use as a named or default FetchGroup
  • Nested FetchGroup and default FetchGroup
    • If a FetchGroup is specified for a relationship that FetchGroup will be used instead the type's default FetchGroup
    • If a null value is specified for a relationship then no FetchGroup will be used on that relationship's target

Download and Try

JAR and SRC.ZIP coming soon

Projects (SVN)

The projects involved in the incubator are:

Additionally you must have the Employee XML example and its dependencies. These can be from trunk or the 1.1.0 branch.

Design

This enhancement's design currently involves 3 relatively simple changes

  • FetchGroup (org.eclipse.persistence.queries)
    • Add a Map of FetchGroup keyed by attribute name to handle the nesting
    • Add accessor methods to get and add nested FetchGroup
    • Add call-back method to apply nested FetchGroup in child queries for relationships
  • FetchGroupManager (org.eclipse.persistence.descriptors)
    • Modify setDefaultFetchGroup to ensure that the newly provided FetchGroup replaces any previously populated value on the ReadObjectQuery cached in the descriptor's query manager.
  • ForeignReferenceMapping (org.eclipse.persistence.mappings)
    • Add a call-back to the FetchGroup (if one exists on the source query) after creating the target query for populating the relationship.


Nested-fetch-group.jpg

Usage Examples

The following usage examples are provided to illustrate how the new nested FetchGroup support will function.

Example: Root with nested 1:1 FetchGroup

Query query = em.createQuery("SELECT e FROM Employee e WHERE e.gender = :GENDER");
query.setParameter("GENDER", Gender.Male);
 
// Define the fields to be fetched on Employee
FetchGroup empGroup = new FetchGroup();
empGroup.addAttribute("firstName");
empGroup.addAttribute("lastName");
empGroup.addAttribute("address");
 
// Define the fields to be fetched on Address
FetchGroup addressGroup = new FetchGroup();
addressGroup.addAttribute("city");
addressGroup.addAttribute("postalCode");
 
empGroup.addGroup("address", addressGroup);
 
// Configure the dynamic FetchGroup
query.setHint(QueryHints.FETCH_GROUP, empGroup);
 
List<Employee> emps = query.getResultList();

Example: Root with nested FetchGroup for 1:1 and null for 1:M

Query query = em.createQuery("SELECT e FROM Employee e WHERE e.gender = :GENDER");
query.setParameter("GENDER", Gender.Male);
 
// Define the fields to be fetched on Employee
FetchGroup empGroup = new FetchGroup();
empGroup.addAttribute("firstName");
empGroup.addAttribute("lastName");
empGroup.addAttribute("address");
 
// Define the fields to be fetched on Address
FetchGroup addressGroup = new FetchGroup();
addressGroup.addAttribute("city");
addressGroup.addAttribute("postalCode");
 
empGroup.addGroup("address", addressGroup);
empGroup.addGroup("phoneNumbers", null);
 
// Configure the dynamic FetchGroup
query.setHint(QueryHints.FETCH_GROUP, empGroup);
 
List<Employee> emps = query.getResultList();

Open Issues

  • Should a relationships specified in a FetchGroup be forced to load before returning from the initiating query? At present the specification of a relationship attribute will only cause its required fields to be read to build the query for the relationship. If the relationship is configured for lazy loading then the created query will only be triggered when the application uses it.
  • Should all of the attribute names used in the FetchGroup(s) be validated against the mappings or should they simply be used if they match and ignored otherwise?
  • For a nested FetchGroup should a developer be able to specify the use of a pre-defined named FetchGroup? Currently this is not supported
  • How are relationships treated that point to a superclass? How can one specify a fetchgroup for each individual subclass?