Community
Participate
Working Groups
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>
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");
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.
================================= 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
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
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.
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
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.
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.
The Eclipselink project has moved to Github: https://github.com/eclipse-ee4j/eclipselink