Skip to main content

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.

Jump to: navigation, search

Difference between revisions of "EclipseLink/Development/2.1/AdvancedJPA Queries/FetchGroup"

(Querying)
Line 14: Line 14:
 
The enhancement to FetchGroup support will include addressing the following requirements:
 
The enhancement to FetchGroup support will include addressing the following requirements:
  
# Support defining FetchGroups that define what should be loaded including basic, embedded attributes, and relationships
+
'''Configuration'''
#* Default FetchGroup for an entity type is defined based on the fetch (lazy loading) configuration of the attributes. For default FetchGroup only the attributes on the entity class itself and those available through inheritance are included.
+
# Default FetchGroup will be defined when one or more basic mappings are configured LAZY and the entity class implements FetchGroupTracker (typically introduced through weaving).
#* Named FetchGroup can be defined using Annotations (@FetchGroup), eclipselink-orm.xml, and API (typically in customizer). Only one named FetchGroup of a given name can exist for an entity type. Note: They can be overridden in inheritance hierarchies using the same name.
+
#* The default FetchGroup defined by mappings will not involve relationships
#* Dynamic FetchGroup can be specified to override
+
#* The default FetchGroup can be customized through API
# FetchGroup can be used on any object-level query (ReadAllQuery, ObjectLevelReadQuery, JPA find)
+
# Named FetchGroup can be defined using annotations, eclispelink-orm.xml, or API
#* If a FetchGroup is specified on a query directly or through the application of a JPA query hint it will be used and applied to the query result
+
# A FetchGroup is assumed to include all required attributes even if not specified. These required attributes will be added to the FetchGroup when it is initialzied
#* If no FetchGroup is specified but a FetchGroup name is configured, either directly or through JAP query hint, then the named FetchGroup will be looked up through the descriptor and its parents hierarchy during query prepare and used if found. If not found an exception should be thrown
+
#* Initialization of default and named FetchGroup occurs when the FetchGroup manager is initialized
#* If no FetchGroup of FetchGroup name is specified on a query then the default FetchGroup looked up through the entity type's descriptor hierarchy will be used.
+
#* Dynamic FetchGroup are initialized when first used.
#* The FetchGroup specified, looked up by name, or looked up as default should not be cached in the query except during actual execution. This will allow FetchGroupManager changes to default and named FetchGroup to be used on subsequent query executions.
+
 
# FetchGroup can be used to detach/copy and entity or collection of entities
+
'''Query Usage'''
#* JpaHelper.copy(Object entity, FetchGroup fetchGroup)
+
# The default FetchGroup is used on any query/find operation when no FetchGroup is specified
#* detached entities with a FetchGroup will have a special DetachedFetchGroup attached that extends its definition based on state changes made to the Entity.  
+
#* A query/find can be customized to not use the default FetchGroup.
#** An exception will be thrown if a DetachedFetchGroup is on an entity and an unfetched attribute is attempted to be fetched.
+
# A named FetchGroup can be specified that will be used if it exists
# FetchGroup can be used to merge entities
+
#* Can be specified using JPA query hint or directly on the native query object
#* If a FetchGroup exists on an entity (FetchGroupTarcker._persistence_getFetchGroup) being merged in EntityManager.merge or UnitOfWork.merge then only the attributes specified in the FetchGroup will be merged.
+
#* If the named FetchGroup cannot be found in the descriptor hierarchy none will be used a warning message logged
 +
 
 +
'''Cached Entities'''
 +
# If an entity is already cached (shared, isolated, UOW) then the resulting entity must have all of the items specified in the FetchGroup loaded. This could result in the triggering of an existing FetchGroup if the previous FetchGroup does not fully include the query specified FetchGroup.  
 +
#* When returning an entity that is partial the FetchGroup MUST always include all items that are populated
 +
 
 +
'''Detaching Partial Entities'''
 +
# Entities that are detached when they are partially populated based on a FetchGroup must maintain a FetchGroup in their state so that what has been loaded versus what has not been is known.
 +
# Attempts to access unfetched attributes will cause an exception to be thrown
 +
# Modifying the state of a partial entity will cause its detached FetchGroup to be enhanced to include additional attributes that are set
 +
#* in the case of collections the full collection must be set
 +
# When a partial entity with a FetchGroup is merged into a persistence context only those items defined in the FetchGroup will be merged
 +
#* The cascade MERGE configurations on the mappings will be used and thus items in the FetchGroup without cascade MERGE configured will be ignored.
  
 
== Usage Examples==
 
== Usage Examples==
 +
 +
The following usage examples are provided to assist in the understanding of this new functionality. The complete implementation details are cobvered in the design section of this specification.
  
 
=== Configuration ===
 
=== Configuration ===
 +
 +
In order to use a FetchGroup developers must configure default, named, or dynamic FetchGroup instances for use in queries, copying, and merging of entities.
  
 
==== Default FetchGroup ====
 
==== Default FetchGroup ====
Line 50: Line 66:
 
A named FetchGroup can be configured through annotations or API (DecsriptorCustomizer). This feature includes extensions to the @FetchGroup annotation and eclipselink-orm.xml to support defining FetchGroup items for relationships.
 
A named FetchGroup can be configured through annotations or API (DecsriptorCustomizer). This feature includes extensions to the @FetchGroup annotation and eclipselink-orm.xml to support defining FetchGroup items for relationships.
  
'''Annotation Example'''
+
'''Simple Annotation Example'''
 
<source lang="java">
 
<source lang="java">
 +
@Entity
 +
@FetchGroup(name="named-example", attributes={
 +
        @FetchAttribute(name="id"),
 +
        @FetchAttribute(name="version"),
 +
        @FetchAttribute(name="name"),
 +
})
 +
public class MyEntity {
 +
 +
    @Id
 +
    private int id;
 +
   
 +
    @Version
 +
    private long version;
 +
   
 +
    private String name;
 +
   
 +
    private int size;
 
</source>
 
</source>
 +
 +
'''Relationships Annotation Example'''
 +
<source lang="java">
 +
@Entity
 +
@FetchGroup(name="named-example", attributes={
 +
        @FetchAttribute(name="id"),
 +
        @FetchAttribute(name="version"),
 +
        @FetchAttribute(name="firstName"),
 +
        @FetchAttribute(name="lastName"),
 +
        @FetchAttribute(name="address.city"),
 +
})
 +
public class Employee{
 +
</source>
 +
  
 
'''EclipseLink ORM XML Example'''
 
'''EclipseLink ORM XML Example'''
Line 93: Line 140:
 
List<Employee> emps = query.getResultList();
 
List<Employee> emps = query.getResultList();
 
</source>
 
</source>
 +
 +
=== Detached Entities ===
 +
 +
The following usage examples illustrate how a FetchGroup can be used with detached entities.
  
 
== Design ==
 
== Design ==

Revision as of 11:46, 6 April 2010

EclipseLink 2.1: Enhanced FetchGroup Support

This feature will make major enhancements to EclipseLink's existing FetchGroup support to extends its use beyond lazy loading of basics to encompass full graph definition and usage with queries (including find), detach/copy, and merge.

Related Bugs

Requirements

This feature will enhance FetchGroup to address the following requirements:

The enhancement to FetchGroup support will include addressing the following requirements:

Configuration

  1. Default FetchGroup will be defined when one or more basic mappings are configured LAZY and the entity class implements FetchGroupTracker (typically introduced through weaving).
    • The default FetchGroup defined by mappings will not involve relationships
    • The default FetchGroup can be customized through API
  2. Named FetchGroup can be defined using annotations, eclispelink-orm.xml, or API
  3. A FetchGroup is assumed to include all required attributes even if not specified. These required attributes will be added to the FetchGroup when it is initialzied
    • Initialization of default and named FetchGroup occurs when the FetchGroup manager is initialized
    • Dynamic FetchGroup are initialized when first used.

Query Usage

  1. The default FetchGroup is used on any query/find operation when no FetchGroup is specified
    • A query/find can be customized to not use the default FetchGroup.
  2. A named FetchGroup can be specified that will be used if it exists
    • Can be specified using JPA query hint or directly on the native query object
    • If the named FetchGroup cannot be found in the descriptor hierarchy none will be used a warning message logged

Cached Entities

  1. If an entity is already cached (shared, isolated, UOW) then the resulting entity must have all of the items specified in the FetchGroup loaded. This could result in the triggering of an existing FetchGroup if the previous FetchGroup does not fully include the query specified FetchGroup.
    • When returning an entity that is partial the FetchGroup MUST always include all items that are populated

Detaching Partial Entities

  1. Entities that are detached when they are partially populated based on a FetchGroup must maintain a FetchGroup in their state so that what has been loaded versus what has not been is known.
  2. Attempts to access unfetched attributes will cause an exception to be thrown
  3. Modifying the state of a partial entity will cause its detached FetchGroup to be enhanced to include additional attributes that are set
    • in the case of collections the full collection must be set
  4. When a partial entity with a FetchGroup is merged into a persistence context only those items defined in the FetchGroup will be merged
    • The cascade MERGE configurations on the mappings will be used and thus items in the FetchGroup without cascade MERGE configured will be ignored.

Usage Examples

The following usage examples are provided to assist in the understanding of this new functionality. The complete implementation details are cobvered in the design section of this specification.

Configuration

In order to use a FetchGroup developers must configure default, named, or dynamic FetchGroup instances for use in queries, copying, and merging of entities.

Default FetchGroup

The default FetchGroup is determined through the use of fetch=LAZY on basic mappings. There is no support for relationships in default the default FetchGroup unless the default FetchGroup is manually configured on an entity type's descriptor using API (DescritporCustomizer).

DescriptorCustomizer Example

FetchGroup phoneFG = new FetchGroup();
phoneFG.addAttribute("number");
ClassDescriptor phoneDescriptor = session.getClassDescriptor(PhoneNumber.class);
phoneDescriptor.getFetchGroupManager().setDefaultFetchGroup(phoneFG);

Named FetchGroup

A named FetchGroup can be configured through annotations or API (DecsriptorCustomizer). This feature includes extensions to the @FetchGroup annotation and eclipselink-orm.xml to support defining FetchGroup items for relationships.

Simple Annotation Example

@Entity
@FetchGroup(name="named-example", attributes={
        @FetchAttribute(name="id"), 
        @FetchAttribute(name="version"), 
        @FetchAttribute(name="name"), 
})
public class MyEntity {
 
    @Id
    private int id;
 
    @Version
    private long version;
 
    private String name;
 
    private int size;

Relationships Annotation Example

@Entity
@FetchGroup(name="named-example", attributes={
        @FetchAttribute(name="id"), 
        @FetchAttribute(name="version"), 
        @FetchAttribute(name="firstName"), 
        @FetchAttribute(name="lastName"), 
        @FetchAttribute(name="address.city"), 
})
public class Employee{


EclipseLink ORM XML Example

 


Descriptor Customizer Example

 

Querying

A FetchGroup is used in the processing of a query when a default FetchGroup exists on the entity type's descriptor or one is specified on the query.

Named FetchGroup Example

Query query = em.createQuery("SELECT e FROM Employee e WHERE e.id = :ID");
query.setParameter("ID", Queries.minimumEmployeeId(em));
query.setHint(QueryHints.FETCH_GROUP_NAME, "test");

Dynamic FetchGroup Example

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 fg = new FetchGroup();
fg.addAttribute("id");
fg.addAttribute("version");
fg.addAttribute("firstName");
fg.addAttribute("lastName");
fg.addAttribute("address.city");
fg.addAttribute("address.postalCode");
 
// Configure the dynamic FetchGroup
query.setHint(QueryHints.FETCH_GROUP, fg);
 
List<Employee> emps = query.getResultList();

Detached Entities

The following usage examples illustrate how a FetchGroup can be used with detached entities.

Design

FetchGroup

Query Execution

Detached Entities

Back to the top