Notice: This Wiki is now read only and edits are no longer possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.
EclipseLink/Development/Incubator/Extensions/NestedFetchGroup
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
|
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.
- trunk examples
- 1.1.0 branch examples
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.
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?