This Bugzilla instance is deprecated, and most Eclipse projects now use GitHub or Eclipse GitLab. Please see the deprecation plan for details.
Bug 211322 - Add fetch-group(s) support to the EclipseLink-ORM.XML Schema
Summary: Add fetch-group(s) support to the EclipseLink-ORM.XML Schema
Status: RESOLVED FIXED
Alias: None
Product: z_Archived
Classification: Eclipse Foundation
Component: Eclipselink (show other bugs)
Version: unspecified   Edit
Hardware: PC Windows XP
: P2 enhancement with 1 vote (vote)
Target Milestone: ---   Edit
Assignee: Nobody - feel free to take it CLA
QA Contact:
URL:
Whiteboard: eclipselink-orm.xml
Keywords:
Depends on:
Blocks: 227219
  Show dependency tree
 
Reported: 2007-11-28 14:47 EST by Guy Pelletier CLA
Modified: 2022-06-09 10:26 EDT (History)
4 users (show)

See Also:


Attachments
Proposed changes (99.11 KB, patch)
2010-01-19 14:39 EST, Guy Pelletier CLA
no flags Details | Diff
Amendment to fix nightly tests (31.54 KB, patch)
2010-01-21 14:44 EST, Guy Pelletier CLA
no flags Details | Diff
Amendment to fix nightly tests (33.01 KB, patch)
2010-01-21 15:30 EST, Guy Pelletier CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Guy Pelletier CLA 2007-11-28 14:47:14 EST
 
Comment 1 Doug Clarke CLA 2008-01-31 15:03:39 EST
Need support for:

1. Defining one or more FetchGroup at the entity level in annotations or XML
2. Configuring the usage of an entity defined FetchGroup within a JPA Query. This will require a hint that takes a fetch-group name as a string.
3. Configuring the dynamic use of a fetch group by passing the fetch group object into a query hint dynamically. Ideally the same query hint (eclipselink.fetch-group) should accept both a String (pre-defined group) or a FetchGroup object.

ANNOTATION ON ENTITY:

@Entity
@FetchGroup(name="default", attributes={
   @FetchAttribute(name="firstName"),
   @FetchAttribute(name="lastName")
})
public class Employee { ...

MULTIPLE FetchGroups on an Entity using ANNOTATIONS:

@Entity
@FetchGroups({
   @FetchGroup(name="default", attributes={
      @FetchAttribute(name="firstName"),
      @FetchAttribute(name="lastName")
   })
   @FetchGroup(name="group2", attributes={
      @FetchAttribute(name="firstName"),
      @FetchAttribute(name="lastName"),
      @FetchAttribute(name="salary"),
      @FetchAttribute(name="gender")
   }),
})
public class Employee { ...

SINGLE FetchGroup IN XML:

<entity class="model.Employee">
   <fetch-group name="default">
      <attribute name="firstName"/>
      <attribute name="lastName"/>
   </fetch-group>
   ...
</entity>

MULTIPLE FetchGroups on an Entity using XML:

<entity class="model.Employee">  
   <fetch-group name="default">
      <attribute name="firstName"/>
      <attribute name="lastName"/>
   </fetch-group>
   <fetch-group name="group2">
      <attribute name="firstName"/>
      <attribute name="lastName"/>
      <attribute name="salary"/>
      <attribute name="gender"/>
   </fetch-group>
   ...
</entity>


Comment 2 Shaun Smith CLA 2008-02-12 17:18:15 EST
I'd expect the scope of a FetchGroup to be Entity but how can it be reference for use in a Query?  In Bug 218706 I describe how to set a FetchGroup object on a query with a hint but how would that work when the FetchGroup is defined in an annotation and not code? See below. Suggestions?

@Entity
@FetchGroup(name="first-and-last", attributes={
   @FetchAttribute(name="firstName"),
   @FetchAttribute(name="lastName")
})
public class Employee { ...


Query query = em
   .createNamedQuery("Employee.findByStatus")
   .setHint(EclipseLinkQueryHints.FETCHGROUP, ????????)
   .setParameter("status", "active");
Comment 3 Tom Ware CLA 2009-04-16 10:59:03 EDT
Updating priority due to revised bug categorization process.  See the following page for details:

http://wiki.eclipse.org/EclipseLink/Development/Bugs/Guidelines#Priority_and_Target_Milestone 

If you feel the updated priority is incorrect, please send an email to eclipselink-users@eclipse.org.
Comment 4 Guy Pelletier CLA 2009-12-08 09:13:47 EST
Updating priority due to revised bug categorization process.  See the following
page for details:

http://wiki.eclipse.org/EclipseLink/Development/Bugs/Guidelines#Priority_and_Target_Milestone 

If you feel the updated priority is incorrect, please send an email to
eclipselink-users@eclipse.org.
Comment 5 Guy Pelletier CLA 2010-01-08 13:52:05 EST
================================= ANNOTATIONS =================================

@Target({TYPE})
@Retention(RUNTIME)
public @interface FetchGroup {
    /**
     * (Optional) Fetch group name, no name defaults into the default fetch
     * group for the entity where it is defined.
     */
    String name() default "default"; 

    /**
     * (Required) The list of attributes to fetch.
     */
    String[] attributes;
}

@Target({TYPE})
@Retention(RUNTIME)
public @interface FetchGroups {
    /**
     * (Required) 
     */
    FetchGroup[] value(); 
}

================================= XML =================================

<xsd:complexType name="fetch-group">
  <xsd:annotation>
    <xsd:documentation>

      @Target({TYPE})
      @Retention(RUNTIME)
      public @interface FetchGroup {
        /**
         * (Optional) Fetch group name, no name defaults into the default fetch
         * group for that entity where defined.
         */
        String name() default "default"; 

        /**
         * (Required) The list of attributes to fetch.
         */
        String[] attributes;
      }

    </xsd:documentation>
  </xsd:annotation>
  <xsd:sequence>
    <xsd:element name="attribute" type="xsd:string" minOccurs="0" maxOccurs="unbounded"/>
  </xsd:sequence>
  <xsd:attribute name="name" type="xsd:string"/>
</xsd:complexType>

============================== EXAMPLE 1 ======================================

@FetchGroup(name="default", attributes={"firstName, lastName"}
public Employee {

  ...

}

<entity name="Employee/>
  ...

  <fetch-group name="default">
    <attribute name="firstName"/>
    <attribute name="lastName"/>
  </fetch-group>

  ...
</entity>

============================== EXAMPLE 2 ======================================

@FetchGroups({
  @FetchGroup(attributes={"firstName, lastName"}), // defaults to the default fetch group
  @FetchGroup(name="extended", attributes={"firstName", "lastName", "salary", "gender"})
})
public Employee {

  ...

}

<entity name="Employee/>
  ...

  <fetch-group>
    <attribute name="firstName"/>
    <attribute name="lastName"/>
  </fetch-group>
  <fetch-group name="extended">
    <attribute name="firstName"/>
    <attribute name="lastName"/>
    <attribute name="salary"/>
    <attribute name="gender"/>
  </fetch-group>

  ...
</entity>


=============================== WHERE TO SPECIFY ==============================

 - Can only be specified at the TYPE level.
 - Can be specified on an Entity or MappedSuperclass.

================================= INTERNAL API  ===============================

- for each fetch group create an org.eclipse.persistence.queries.FetchGroup
  name() - fetchGroup.setName();
  attributes() - fetchGroup.addAttributes();

- create a org.eclipse.persistence.descriptors.FetchGroupManager
  if fetch group name is equal to the default, 
   - fetchGroupManager.setDefaultFetchGroup(fetchGroup);
  else 
   - fetchGroupManager.addFetchGroup(fetchGroup);

- finally add the fetch group manager to the descriptor
  - descriptor.setFetchGroupManager(fetchGroupManager)

================================= EXCEPTIONS ==================================

- Multiple fetch groups with the same name for one entity.

=========================== OVERRIDDING AND MERGING ===========================

- Existing XML overriding and merging rules apply. eclipselink-orm.xml fetch 
groups will override those from other mappings files with the same name for the
same entity and mapped superclass.

=========================== FETCH GROUP FROM QUERY ============================

- James already addressed referencing a fetch group through a query hint in bug 
251594, namely: eclipselink.fetch-group.name
Comment 6 Guy Pelletier CLA 2010-01-11 08:53:20 EST
Update after discussion with Doug Clarke.

Fetch groups will be used as a way of adding named fetch groups only. The 
default fetch will not be affected through the use of this metadata. The 
default fetch  group can be controlled by marking basic attributes as lazy 
(current implementation/behavior)

================================= ANNOTATIONS =================================

@Target({TYPE})
@Retention(RUNTIME)
public @interface FetchGroup {
    /**
     * (Required) The fetch group name.
     */
    String name(); 

    /**
     * (Required) The list of attributes to fetch.
     */
    String[] attributes;
}

@Target({TYPE})
@Retention(RUNTIME)
public @interface FetchGroups {
    /**
     * (Required) 
     */
    FetchGroup[] value(); 
}

================================= XML =================================

<xsd:complexType name="fetch-group">
  <xsd:annotation>
    <xsd:documentation>

      @Target({TYPE})
      @Retention(RUNTIME)
      public @interface FetchGroup {
        /**
         * (Required) The fetch group name.
         */
        String name(); 

        /**
         * (Required) The list of attributes to fetch.
         */
        String[] attributes;
      }

    </xsd:documentation>
  </xsd:annotation>
  <xsd:sequence>
    <xsd:element name="attribute" type="xsd:string" minOccurs="0" maxOccurs="unbounded"/>
  </xsd:sequence>
  <xsd:attribute name="name" type="xsd:string" use="required"/>
</xsd:complexType>

============================== EXAMPLE 1 ======================================

@FetchGroup(name="simple", attributes={"firstName, lastName"}
public Employee {

  ...

}

<entity name="Employee/>
  ...

  <fetch-group name="simple">
    <attribute name="firstName"/>
    <attribute name="lastName"/>
  </fetch-group>

  ...
</entity>

============================== EXAMPLE 2 ======================================

@FetchGroups({
  @FetchGroup(name="simple", attributes={"firstName, lastName"}),
  @FetchGroup(name="extended", attributes={"firstName", "lastName", "salary", "gender"})
})
public Employee {

  ...

}

<entity name="Employee/>
  ...

  <fetch-group name="simple">
    <attribute name="firstName"/>
    <attribute name="lastName"/>
  </fetch-group>
  <fetch-group name="extended">
    <attribute name="firstName"/>
    <attribute name="lastName"/>
    <attribute name="salary"/>
    <attribute name="gender"/>
  </fetch-group>

  ...
</entity>


=============================== WHERE TO SPECIFY ==============================

 - Can only be specified at the TYPE level.
 - Can be specified on an Entity or MappedSuperclass.
 - Inheritance: 
    - From what I can tell named fetch groups are currently not inherited but
      there is no reason to not allow this. Therefore, within this work an
      inherited named fetch group scenario will be tested and corrected if
      necessary to allow this behavior.

==================================== WEAVING ==================================

 - We must ensure we weave the FetchGroupTracker interface for those entities
   specifying a fetch group(s)

================================= INTERNAL API  ===============================

- for each fetch group create an org.eclipse.persistence.queries.FetchGroup
  name() - fetchGroup.setName();
  attributes() - fetchGroup.addAttributes();

- create a org.eclipse.persistence.descriptors.FetchGroupManager and add the
  fetch groups
   - fetchGroupManager.addFetchGroup(fetchGroup);

- finally add the fetch group manager to the descriptor
  - descriptor.setFetchGroupManager(fetchGroupManager)

================================= EXCEPTIONS ==================================

- Multiple fetch groups with the same name for one entity.

=========================== OVERRIDDING AND MERGING ===========================

- Existing XML overriding and merging rules apply. eclipselink-orm.xml fetch 
groups will override those from other mappings files with the same name for the
same entity and mapped superclass.

=========================== FETCH GROUP FROM QUERY ============================

- James already addressed referencing a fetch group through a query hint in bug 
251594, namely: eclipselink.fetch-group.name

=================================== FUTURE ====================================

- Expand implementation to support nested fetch groups:
http://wiki.eclipse.org/EclipseLink/Development/Incubator/Extensions/NestedFetchGroup
Comment 7 Guy Pelletier CLA 2010-01-19 14:39:12 EST
Created attachment 156552 [details]
Proposed changes

Note:

After some discussions with Doug, we've gone back to using the @FetchAttribute and equivalent fetch-attribute complex-type to allow for future extensions to the fetch group feature.
Comment 8 Guy Pelletier CLA 2010-01-20 07:39:27 EST
Changes were submitted.  

Reviewed by: Chris Delahunt
 
Added new models and tests:
org.eclipse.persistence.testing.models.jpa.advanced.fetchGroup
org.eclipse.persistence.testing.tests.jpa.advanced.AdvancedFetchGroupJunitTest
org.eclipse.persistence.testing.models.jpa.xml.advanced.fetchGroup
org.eclipse.persistence.testing.tests.jpa.xml.advanced.EntityMappingsFetchGroupJunitTest
Comment 9 Guy Pelletier CLA 2010-01-21 14:44:57 EST
Created attachment 156850 [details]
Amendment to fix nightly tests

Patch to address issue discovered when running nightly tests. Fetch groups are not processed unless weaving is turned on. Specifying fetch groups when weaving is turned off will now result in an exception.
Comment 10 Guy Pelletier CLA 2010-01-21 15:30:19 EST
Created attachment 156862 [details]
Amendment to fix nightly tests

Strike the last patch, we log a warning rather than throw an exception when fetch groups are used outside of weaving.
Comment 11 Eclipse Webmaster CLA 2022-06-09 10:26:22 EDT
The Eclipselink project has moved to Github: https://github.com/eclipse-ee4j/eclipselink