users@jpa-spec.java.net

[jpa-spec users] [jsr338-experts] Re: Proposal for EntityGraphs, fetch plans, etc...

From: Werner Keil <werner.keil_at_gmail.com>
Date: Thu, 29 Nov 2012 17:54:00 +0100

Pinaki/all,

On Wed, Nov 28, 2012 at 9:32 PM, Pinaki Poddar <ppoddar_at_us.ibm.com> wrote:

> Thank you for bringing Fetch Plan for discussion and an extensive proposal
> to realize it.
>
> Few comments:
> 1. The naming could be FetchPlan/FetchAttribute etc as they are more
> commonly used than NamedEntityGraph etc.
>
> Beside OpenJPA and EclipseLink (also as extension to the JPA RI) this term
already existed in the Spec of JDO. If it does the same in all 3 cases, it
might be a good idea. EclipseLink (some Incubator code) calls the
"FetchAttribute" "FetchItem", but I guess if the general proposal was
agreed upon, this is is a detail. In doubt I'd stick to the naming by the
RI, but if everybody thought it was bad, why not consider alternatives.

One argument for the term Graph could be an open mind of JPA towards NoSQL
(e.g. Graph) databases, assuming this proposal would make sense both to
relational and non-relational databases.


> 2. The need for a SubGraph may not be required. If every
> FetchGroup/NamedEntityGraph defined/rooted in entity type X can include
> FetchGroup(s) defined in other entity type Y, then a separate definition of
> SubGraph would not be necessary.
>
> 3. The fetch attributes can simply be persistent property names (i.e.
> Strings) to reduce verbosity of annotations/XML descriptors. The type
> information is already available through MetaModel and entity type
> definitions, so why would the graph specification require them?
>
> This suggests, there will be XML override like in other areas, correct?


> 4. A concept of recursion depth is required on relationship paths to
> control the cycles in a graph.
>
> 5. With our usage of Fetch Plans, we found it useful to control the
> maximum fetch depth (counted as a number of edges from the root to a leaf
> node being fetched)
>
> 6. A lock specification could be an optional qualifier on relation paths
>
> Regards --
>
> Pinaki Poddar
> Chair, Apache OpenJPA Project http://openjpa.apache.org/
> JPA Expert Group Member
> Application & Integration Middleware
>
>
>
> Regards,

 --

Werner Keil | JCP Executive Committee Member | Eclipse UOMo Lead | Java
Godfather

Twitter @wernerkeil | #Java_Social | #EclipseUOMo | #OpenDDR
Skype werner.keil | Google+ gplus.to/wernerkeil


>
>
> [image: Inactive hide details for Gordon Yorke ---11/28/2012 05:32:05
> AM---Hello All, Based on suggestions from a colleague I would]Gordon
> Yorke ---11/28/2012 05:32:05 AM---Hello All, Based on suggestions from
> a colleague I would like to suggest some
>
> From: Gordon Yorke <gordon.yorke_at_oracle.com>
> To: jsr338-experts_at_jpa-spec.java.net
> Date: 11/28/2012 05:32 AM
> Subject: [jsr338-experts] Re: Proposal for EntityGraphs, fetch plans,
> etc...
> ------------------------------
>
>
>
> Hello All,
> Based on suggestions from a colleague I would like to suggest some
> clarification and updates.
> 1 - with respect to @Version add to the proposal that version is always
> fetched and copied along with the PK.
>
> 2 - Add :
> /**
> * returns all named EntityGraphs that have been defined for the
> provided
> * class type.
> */
> public <T> List<EntityGraph<? super T>> getEntityGraphs(Class<T>
> entityClass);
>
> 3 - Fix EntityManager.copy :
> public <X> X copy(X entity, EntityGraph<? super X> entityGraph,
> Map<String, Object> properties);
>
> Thank you,
> --Gordon
>
>
> On 27/11/2012 5:20 PM, Gordon Yorke wrote:
>
> Hello all,
> Please find below a proposal for EntityGraphs and their use to
> define entity graph fetching, loading, merging and copying. I have been
> working with Mike Keith and Linda DeMichiel on this proposal and we feel it
> is time to present to the expert group. Please have a look and provide
> feedback as the intention is to integrate this within the 2.1 spec.
> Thank you,
> Gordon
>
> ----
> A common functional request has been to enable users to dynamically
> define how an EntityManager operation or query should apply to an entity
> graph. This may more commonly be known as “merge groups” or “fetch plans”.
> This functionality can be especially important when detached entities must
> be serialized and then merged into an active Persistence Context.
>
> An entity graph is a template defined in the form of metadata or an
> object created by the dynamic EntityGraph API that captures the path and
> boundaries for an operation or a query For static metadata the
> NamedEntityGraph annotation defines the attribute nodes and boundaries of
> the grouping.
>
> @Target({TYPE})
> @Retention(RUNTIME)
> public @interface NamedEntityGraphs{
> NamedEntityGraph[] value();
> }
>
> @Target({TYPE})
> @Retention(RUNTIME)
> public @interface NamedEntityGraph{
> /**
> * (Optional) The name of the sub-graph.
> * Defaults to the entity name of the root entity.
> */
> String name() default "";
>
> /**
> * (Required) list of attributes that are included in in this
> sub-graph.
> */
> NamedAttributeNode[] attributeNodes();
>
> /**
> * (Optional) Lists all of the attributes of this Entity class to
> be listed in
> * the NamedEntityGraph without the need to explicitly list them.
> Included
> * attributes can still be fully specified by an attribute node
> referencing a
> * sub-graph.
> */
> boolean includeAllAttributes() default false;
>
> /**
> * (Optional) This is a list of sub-graphs that are included in the
> * entity graph. They are referenced by name from
> NamedAttributeNode
> * definitions.
> */
>
> NamedSubGraph[] subGraphs() default {};
>
> /**
> * (Optional) This is a list of sub-graphs that will add additional
> attributes
> * for subclasses of the entity represented by this
> NamedEntityGraph to this
> * entity graph. Specified attributes from superclasses are
> included in
> * subclasses.
> */
>
> NamedSubGraph[] subclassSubGraphs() default {};
> }
>
> The NamedEntityGraph annotation is applied to an Entity class that is
> defined as the root of a group of attributes, relationships and related
> entity classes. The NamedAttributeNode annotations are embedded within the
> NamedEntityGraph metadata and define the attributes of the entity that
> are included in the grouping. When a NamedAttributeNode represents an
> Entity or an Embedded (including a collection-valued relationship or an
> element collection of embeddables), the referenced type’s attributes can be
> included as a NamedSubGraph entry of the entity graph and referenced by
> name, creating a multi-level entity graph. If the sub-graph represents an
> entity with inheritance multiple NamedSubGraph entries can be made with the
> same name to extend the sub-graph for specific subclasses. The class type
> that is being extended is required in the NamedSubGraph.
>
> /**
> * A NamedAttributeNode is a member attribute of a NamedEntityGraph.
> *
> * @see javax.persistence.NamedEntityGraph
> * @see javax.persistence.NamedSubGraph
>
> */
> @Target({})
> @Retention(RUNTIME)
> public @interface NamedAttributeNode {
> /**
> * (Required) the name of the attribute that must be in the
> sub-graph.
> */
> String value();
>
> /**
> * (Optional) if this attribute references a managed type that has
> its own
> * AttributeNodes then this refers to that NamedSubGraph
> definition. If the
> * target type has inheritance than multiple sub graphs can be
> specified.
> * These additional sub-graphs are intended to add additional
> attributes from
> * subclasses. Superclass sub-graph entries will be merged into
> subclasses
> * sub-graphs.
> */
> String subGraph() default “”;
>
> /**
> * (Optional) if the attribute references a Map type this can be
> used to specify
> * a subGraph for the Key in the case of an Entity key type. A
> * keySubGraph can not be specified without the Map attribute also
> being
> * specified. If the target type has inheritance than multiple
> sub-graphs can
> * be specified. These additional sub-graphs are intended to add
> additional
> * attributes from subclasses. Superclass sub-graph entries will be
> merged
> * into subclasses sub-graphs.
> */
> String keySubGraph() default "";
>
> }
>
> /**
> * A NamedSubGraph is a member of a NamedEntityGraph that represents a
> managed
> * type. The NamedSubGraph is only referenced from within a
> NamedEntityGraph and
> * can not be referenced on its own. It is referenced by name from a
> * NamedAttributeNode of the NamedEntityGraph.
> *
> * @see javax.persistence.NamedEntityGraph
> * @see javax.persistence.NamedAttributeNode
> */
> @Target({})
> @Retention(RUNTIME)
> public @interface NamedSubGraph {
> /**
> * (Required) the name of the sub-graph as referenced from a
> * NamedAttributeNode.
> */
> String name();
>
> /**
> * (Optional) the type represented by this subgraph. Required when
> this
> * subgraph is extending a subclass’ definition.
> */
> Class type default void.class;
>
> /** (Required)
> * if this NamedAttributeNode references a managed type then this
> list is
> * the attributes of that type that must be included.
> */
> NamedAttributeNode[] attributeNodes();
>
> }
>
> For example:
> @Entity
> public class Employee{
>
> @Id
> @GeneratedValue
> protected long id;
>
> @Basic
> protected String name;
>
> @Basic
> protected String employeeNumber;
>
> @OneToMany()
> protected List<Dependants> dependants;
>
> @OneToMany()
> protected List<Project> projects;
>
> @OneToMany()
> protected List<PhoneNumber> phoneNumbers;
> ...
> }
>
> @Entity
> @Inheritance
> public class Project{
> @Id
> @GeneratedValue
> protected long id;
>
> @OneToOne(fetch=FetchType.EAGER)
> protected Requirements doc;
> ...
> }
>
> @Entity
> public class LargeProject extends Project{
>
> @OneToOne(fetch=FetchType.LAZY)
> protected Employee approver;
> ...
> }
>
> @Entity
> public class Phonenumber{
> @Id
> protected String number;
>
> protected PhoneTypeEnum type;
> ...
> }
>
> @Entity
> public class Requirements{
> @Id
> protected long id;
>
> @Lob
> protected String description;
>
> @OneToOne(fetch=FetchType.LAZY)
> protected Approval approval
> ...
> }
>
> @NamedEntityGraph(
> attributeNodes={
> @NamedAttributeNode(
> value="projects",
> subGraph=”projects”
> ),
> @NamedttributeNode(name = "phoneNumbers"),
> },
> subGraphs={
> @NamedSubGraph(
> name=”projects”,
> attributeNodes={
> @NamedAttributeNode("requirements")
> }
> ),
> @NamedSubGraph(
> name=”projects”,
> type=LargeProject.class,
> attributeNodes={
> @NamedAttributeNode("approver")
> }
> )
> }
> )
>
> @NamedEntityGraph(
> name-”Project”,
> attributeNodes={
> @NamedAttributeNode("requirements")
> },
> subclassSubGraphs={
> @NamedSubGraph(
> type=LargeProject.class,
> attributeNodes={
> @NamedAttributeNode("approver")
> }
> )
> }
> )
>
> @NamedEntityGraph(
> name="EmployeeProjectRequirements"
> attributeNodes={
> @NamedAttributeNode(
> value="projects",
> subGraph=”projects”
> ),
> @NamedttributeNode(name = "phoneNumbers"),
> },
> subGraphs={
> @NamedSubGraph(
> name=”projects”,
> attributeNodes={
> @NamedAttributeNode(
> value ="requirements",
> subGraph=”requirements”
> )
> }
> ),
> @NamedSubGraph(
> name=”requirements”,
> attributeNodes={
> @NamedAttributeNode("description"),
> @NamedAttributeNode("approval")
> }
> )
> }
> )
>
> The entity graph could also be created dynamically through the
> following APIs:
>
> /**
> * This type represents the root of an entity graph that will be used
> as a
> * template to define the attribute nodes and boundaries of a graph of
> entities and
> * entity relationships. The root must be an Entity type.
> *
> * @param <T>
> * the type of the root entity.
> */
>
> public interface EntityGraph<T> {
>
> /**
> * Returns the name of the static EntityGraph. Will return null if
> the
> * EntityGraph is not a named EntityGraph.
> */
> public String getName();
>
> /*
> * Add an AttributeNode attribute to the entity graph.
> *
> * @throws IllegalArgumentException if the attribute is not an
> attribute of
> * this entity.
> * @throws IllegalStateException if this EntityGraph has been
> statically
> * defined
> */
> public <X> void addAttributeNodes(String ... attributeName);
>
> /*
> * Add an AttributeNode attribute to the entity graph.
> *
> * @throws IllegalStateException if this EntityGraph has been
> statically
> * defined
> */
> public <X> void addAttributeNodes(Attribute<T, X> ... attribute);
>
> /*
> * Used to add a node of the graph that corresponds to a managed
> type. This
> * allows for construction of multi-node Entity graphs that include
> related
> * managed types.
> *
> * @throws IllegalArgumentException if the attribute's target type
> is not a
> * managed type
> *
> * @throws IllegalStateException if this EntityGraph has been
> statically
> * defined
> */
> public <X> SubGraph<X> addSubGraph(Attribute<T, X> attribute);
>
> /**
> * Used to add a node of the graph that corresponds to a managed
> type with
> * inheritance. This allows for multiple subclass sub-graphs to be
> defined
> * for this node of the entity graph. Subclass sub-graphs will
> include the
> * specified attributes of superclass sub-graphs
> *
> * @throws IllegalArgumentException
> * if the attribute's target type is not a managed type
> * @throws IllegalStateException
> * if this EntityGraph has been statically defined
> */
> public <X> SubGraph<? extends X> addSubGraph(Attribute<T, X>
> attribute, Class<? extends X> type);
>
> /*
> * Used to add a node of the graph that corresponds to a managed
> type. This
> * allows for construction of multi-node Entity graphs that include
> related
> * managed types.
> *
> * @throws IllegalArgumentException if the attribute is not an
> attribute of
> * this entity.
> * @throws IllegalArgumentException if the attribute's target type
> is not a
> * managed type
> *
> * @throws IllegalStateException if this EntityGraph has been
> statically
> * defined
> */
> public <X> SubGraph<X> addSubGraph(String attribute);
>
> /**
> * Used to add a node of the graph that corresponds to a managed
> type with
> * inheritance. This allows for multiple subclass sub-graphs to be
> defined
> * for this node of the entity graph. Subclass sub-graphs will
> include the
> * specified attributes of superclass sub-graphs
> *
> * @throws IllegalArgumentException if the attribute is not an
> attribute of
> * this managed type.
> * @throws IllegalArgumentException
> * if the attribute's target type is not a managed type
> * @throws IllegalStateException
> * if this EntityGraph has been statically defined
> */
> public <X> SubGraph<X> addSubGraph(String attribute, Class<X> type);
>
> /*
> * Used to add a node of the graph that corresponds to a map key
> that is a
> * managed type. This allows for construction of multi-node Entity
> graphs that
> * include related managed types.
> *
> * @throws IllegalArgumentException if the attribute's target type
> is not a
> * managed type entity
> *
> * @throws IllegalStateException if this EntityGraph has been
> statically
> * defined
> */
> public <X> SubGraph<X> addKeySubGraph(Attribute<T, X> attribute);
>
> /*
> * Used to add a node of the graph that corresponds to a map key
> that is a
> * managed type with inheritance. This allows for construction of
> multi-
> * node Entity graphs that include related managed types. Subclass
> sub-graphs
> * will include the specified attributes of superclass sub-graphs
> *
> * @throws IllegalArgumentException if the attribute's target type
> is not a
> * managed type entity
>
> *
> * @throws IllegalStateException if this EntityGraph has been
> statically
> * defined
> */
> public <X> SubGraph<? Extends X> addKeySubGraph(Attribute<T, X>
> attribute, Class<? Extends X> type);
>
> /*
> * Used to add a node of the graph that corresponds to a map key
> that is a
> * managed type. This allows for construction of multi-node Entity
> graphs that
> * include related managed types.
> *
> * @throws IllegalArgumentException if the attribute is not an
> attribute of
> * this entity.
> * @throws IllegalArgumentException if the attribute's target type
> is not a
> * managed type
> *
> * @throws IllegalStateException if this EntityGraph has been
> statically
> * defined
> */
> public <X> SubGraph<X> addKeySubGraph(String attribute);
>
> /*
> * Used to add a node of the graph that corresponds to a map key
> that is a
> * managed type with inheritance. This allows for construction of
> multi-
> * node Entity graphs that include related managed types. Subclass
> sub-graphs
> * will include the specified attributes of superclass sub-graphs
> *
> * @throws IllegalArgumentException if the attribute is not an
> attribute of
> * this entity.
> * @throws IllegalArgumentException if the attribute's target type
> is not a
> * managed type
> *
> * @throws IllegalStateException if this EntityGraph has been
> statically
> * defined
> */
> public <X> SubGraph<X> addKeySubGraph(String attribute, Class<X>
> type);
>
> /*
> * returns the attributes of this entity that are included in the
> entity
> * graph
> */
> public List<AttributeNode<?>> getAttributeNodes();
>
> }
>
> /**
> * Represents an AttributeNode of an entity graph.
> */
> public interface AttributeNode<T> {
>
> /*
> * returns the Type of the AttributeNode.
> */
>
>
> public Type<T> getType();
>
> /*
> * returns the name of the referencing attribute.
> */
> public String getAttributeName();
> }
>
> /**
> * This type represents a AttributeNode of an EntityGraph that
> corresponds to a
> * Managed Type. Using this class an entity graph can be embedded
> within an
> * EntityGraph.
> *
> * @param <T>
> * the Class type of the AttributeNode.
> */
>
> public interface SubGraph<T> extends AttributeNode<T> {
>
> /**
> * Add an AttributeNode attribute to the entity graph.
> *
> * @throws IllegalArgumentException if the attribute is not an
> attribute of
> * this managed type.
> * @throws IllegalStateException
> * if this EntityGraph has been statically defined
> */
> public <X> void addAttributeNodes(String ... attributeName);
>
> /**
> * Add an AttributeNode attribute to the entity graph.
> *
> * @throws IllegalStateException
> * if this EntityGraph has been statically defined
> */
> public <X> void addAttributeNodes(Attribute<T, X> ... attribute);
>
> /**
> * Used to add a node of the graph that corresponds to a managed
> type. This
> * allows for construction of multi-node Entity graphs that include
> related
> * managed types.
>
> *
> * @throws IllegalArgumentException
> * if the attribute's target type is not a managed type
> * @throws IllegalStateException
> * if this EntityGraph has been statically defined
> */
> public <X> SubGraph<X> addSubGraph(Attribute<T, X> attribute);
>
> /**
> * Used to add a node of the graph that corresponds to a managed
> type with
> * inheritance. This allows for multiple subclass sub-graphs to be
> defined
> * for this node of the entity graph. Subclass sub-graphs will
> include the
> * specified attributes of superclass sub-graphs
> *
> * @throws IllegalArgumentException
> * if the attribute's target type is not a managed type
> * @throws IllegalStateException
> * if this EntityGraph has been statically defined
> */
> public <X> SubGraph<? extends X> addSubGraph(Attribute<T, X>
> attribute, Class<? extends X> type);
>
> /**
> * Used to add a node of the graph that corresponds to a managed
> type. This
> * allows for construction of multi-node Entity graphs that include
> related
> * managed types.
> *
> * @throws IllegalArgumentException if the attribute is not an
> attribute of
> * this managed type.
> * @throws IllegalArgumentException
> * if the attribute's target type is not a managed type
> * @throws IllegalStateException
> * if this EntityGraph has been statically defined
> */
> public <X> SubGraph<X> addSubGraph(String attribute);
>
> /**
> * Used to add a node of the graph that corresponds to a managed
> type with
> * inheritance. This allows for multiple subclass sub-graphs to be
> defined
> * for this node of the entity graph. Subclass sub-graphs will
> include the
> * specified attributes of superclass sub-graphs
> *
> * @throws IllegalArgumentException if the attribute is not an
> attribute of
> * this managed type.
> * @throws IllegalArgumentException
> * if the attribute's target type is not a managed type
> * @throws IllegalStateException
> * if this EntityGraph has been statically defined
> */
> public <X> SubGraph<X> addSubGraph(String attribute, Class<X> type);
>
> /*
> * Used to add a node of the graph that corresponds to a map key
> that is a
> * managed type. This allows for construction of multi-node Entity
> graphs that
> * include related managed types.
> *
> * @throws IllegalArgumentException if the attribute's target type
> is not a
> * managed type entity
>
> *
> * @throws IllegalStateException if this EntityGraph has been
> statically
> * defined
> */
> public <X> SubGraph<X> addKeySubGraph(Attribute<T, X> attribute);
>
> /*
> * Used to add a node of the graph that corresponds to a map key
> that is a
> * managed type with inheritance. This allows for construction of
> multi-
> * node Entity graphs that include related managed types. Subclass
> sub-graphs
> * will include the specified attributes of superclass sub-graphs
> *
> * @throws IllegalArgumentException if the attribute's target type
> is not a
> * managed type entity
>
> *
> * @throws IllegalStateException if this EntityGraph has been
> statically
> * defined
> */
> public <X> SubGraph<? Extends X> addKeySubGraph(Attribute<T, X>
> attribute, Class<? Extends X> type);
>
> /*
> * Used to add a node of the graph that corresponds to a map key
> that is a
> * managed type. This allows for construction of multi-node Entity
> graphs that
> * include related managed types.
> *
> * @throws IllegalArgumentException if the attribute is not an
> attribute of
> * this entity.
> * @throws IllegalArgumentException if the attribute's target type
> is not a
> * managed type
> *
> * @throws IllegalStateException if this EntityGraph has been
> statically
> * defined
> */
> public <X> SubGraph<X> addKeySubGraph(String attribute);
>
> /*
> * Used to add a node of the graph that corresponds to a map key
> that is a
> * managed type with inheritance. This allows for construction of
> multi-
> * node Entity graphs that include related managed types. Subclass
> sub-graphs
> * will include the specified attributes of superclass sub-graphs
> *
> * @throws IllegalArgumentException if the attribute is not an
> attribute of
> * this entity.
> * @throws IllegalArgumentException if the attribute's target type
> is not a
> * managed type
> *
> * @throws IllegalStateException if this EntityGraph has been
> statically
> * defined
> */
> public <X> SubGraph<X> addKeySubGraph(String attribute, Class<X>
> type);
>
> /**
> * returns the attributes of this managed type that are included in
> the
> * sub-graph
> */
> public List<AttributeNode<?>> getAttributeNodes();
>
> /**
> * returns the attribute that references this sub-graph.
> /
> public <T> Attribute<T,X> getReferencingAttribute();
>
> /**
> * returns the type of this sub-graph if it was used to extend a
> superclass’
> * sub-graph definition.
> */
> public Class<X> getClassType();
> }
>
> public interface EntityManagerFactory {
> ...
> /**
> * returns any named EntityGraph that has been created through
> static
> * metadata. Returned EntityGraphs should be considered immutable.
> */
> public <T> EntityGraph<T> getEntityGraph(String graphName);
>
> /**
> * add a named copy of the EntityGraph to the EntityManagerFactory
> */
> public void addNamedEntityGraph(String graphName, EntityGraph
> entityGraph);
>
> /**
> * returns a mutable EntityGraph that can be used to dynamically
> create an
> * EntityGraph.
> */
> public <T> EntityGraph<T> createEntityGraph(Class<T> rootType);
>
> /**
> * returns a mutable copy of the named EntityGraph
> */
> public EntityGraph<?> createEntityGraph(String graphName);
>
> Example:
>
> EntityGroup employee = emf.createEntityGraph(Employee.class);
> employee.addAttributeNode("phoneNumbers");
> SubGraph projects = employee.addSubGraph("projects");
> projects.addAttributeNode("requirements");
> SubGraph largeProjects = employee.addSubGraph(“projects”,
> LargeProject.class);
> largeProjects.addAttributeNode(“approver”);
>
> EntityGroup employee = emf.createEntityGraph(Employee.class);
> employee.addAttributeNode("phoneNumbers");
> SubGraph requirements = employee.addSubGraph("projects")
> .addSubGraph("requirements");
> requirements.addAttributeNode("description");
> requirements.addAttributeNode("approval");
>
> Once the EntityGraph is available or has been created it can be
> applied to operations on the EntityManager or used with queries to control
> eager loading of results.
>
> The standard property javax.persistence.fetchgraph can be used with
> the find operation or as a query hint to specify a EntityGraph that defines
> additional FetchType semantics whereby any AttributeNode of the
> EntityGraph is treated as FetchType.EAGER and any attribute not
> specified in the EntityGraph is treated as FetchType.LAZY. The
> primary key of an entity is always retrieved even if not present in the
> fetch group.
>
> The following characterizes the semantics of entity graphs that are
> used as fetch graphs.
>
> A fetch graph attribute node specified within an entity graph or
> sub-graph specifies how an attribute is to be fetched. Attributes that are
> not specified are treated as FetchType.LAZY.
>
> The following rules apply, depending on attribute type.
>
> A primary key attribute never needs to be specified in an attribute
> node. (This applies to composite primary keys as well, including embedded
> id primary keys.) When an entity is fetched, its primary key is always
> fetched. It is not incorrect, however, to specify primary key attributes.
>
> Attributes other than primary key attributes are not fetched unless
> the attribute is specified. The following rules apply to the specification
> of attributes:
>
> The default fetch graph for an entity or embeddable consists of the
> transitive closure of all of its attributes that are specified as
> FetchType.EAGER (or defaulted as such).
>
> If the attribute is an embedded attribute, and the attribute is
> specified in an attribute node, but a subgraph is not specified for the
> attribute, the default fetch graph for the embeddable is fetched. If a
> subgraph is specified for the attribute, the attributes of the embeddable
> are fetched according to their specification in the corresponding subgraph,
> and the rules of this section recursively apply.
>
> If the attribute is an element collection of basic type, and the
> attribute is specified in an attribute node, the element collection
> together with its basic elements is fetched.
>
> If the attribute is an element collection of embeddables, and the
> attribute is specified in an attribute node, but a subgraph is not
> specified for the attribute, the element collection together with the
> default fetch graph of its embeddable elements is fetched. If a subgraph
> is specified for the attribute, the attributes of the embeddable elements
> will be fetched according to the corresponding subgraph specification, and
> the rules of this section recursively apply.
>
> If the attribute is a one-to-one or many-to-one relationship, and the
> attribute is specified in an attribute node, but a subgraph is not
> specified for the attribute, the default fetch graph of the target entity
> is fetched. If a subgraph is specified for the attribute, the attributes
> of the target entity will be fetched according to the corresponding
> subgraph specification, and the rules of this section recursively apply.
>
> If the attribute is a one-to-many or many-to-many relationship, and
> the attribute is specified in an attribute node, but a subgraph is not
> specified, the collection will be fetched and the default fetch graphs of
> the referenced entities will be fetched. If a subgraph is specified for
> the attribute, the entities in the collection will be fetched according to
> the corresponding subgraph specification, and the rules of this section
> recursively apply.
>
> If the key of a map which has been specified in an attribute node is a
> basic type, it will always be fetched and if the key of a map which has
> been specified in an attribute node is an embedded type the default fetch
> graph will be fetched for the embeddable; otherwise, if a map key subgraph
> is not specified for the attribute node, the map key will be fetched
> according to its default fetch graph. If a key subgraph is specified for
> the map key attribute, the map key attribute will be fetched according to
> the map key subgraph specification, and the rules of this section
> recursively apply.
>
> So using the following entity graph:
>
> @NamedEntityGraph(
> )
>
> used to load a Phonenumber only the id and the FKs would be retrieved.
>
>
> When using the following entity graph:
> @NamedEntityGraph(
> attributeNodes={
> @NamedAttributeNode("projects"),
> }
> )
>
> loading an Employee the PKs and FKs would be retrieved and the
> “projects” attribute would be eagerly loaded.
>
> The standard property javax.persistence.loadgraph can be used to
> specify an entity graph that defines additional FetchType semantics with
> any attribute node of the entity graph becoming FetchType.EAGER and
> any unspecified attributes remain as defined in the mapping.
>
> The following characterizes the semantics of entity graphs that are
> used as load graphs.
>
> A load graph attribute node specified within an entity graph or
> sub-graph specifies how an attribute is to be fetched. Attributes that are
> not specified are treated according to their default FetchType.
>
> The following rules apply to the specification of attributes:
>
> A primary key attribute never needs to be specified in an attribute
> node. (This applies to composite primary keys as well, including embedded
> id primary keys.) When an entity is fetched, its primary key is always
> fetched. It is not incorrect, however, to specify primary key attributes.
>
> If the attribute is an embedded attribute, and the attribute is
> specified in an attribute node, but a subgraph is not specified for the
> attribute, the default fetch graph for the embeddable is fetched. If a
> subgraph is specified for the attribute, any attributes of the embeddable
> that are not further specified within the subgraph are treated according to
> their fetch type; attributes that are specified by the subgraph are also
> fetched; and the rules of this section recursively apply.
>
> If the attribute is an element collection of basic type, and the
> attribute is specified in an attribute node, the element collection
> together with its basic elements is fetched. If the attribute is an
> element collection of embeddables, and the attribute is specified in an
> attribute node, but a subgraph is not specified for the attribute, the
> element collection together with the default fetch graph of its embeddable
> elements is fetched. If a subgraph is specified for the attribute, any
> attributes of the embeddables that are not further specified are treated
> according to their fetch type; attributes that are specified by the
> subgraph are also fetched; and the rules of this section recursively apply.
>
> If the attribute is a one-to-one or many-to-one relationship, and the
> attribute is specified in an attribute node, but a subgraph is not
> specified for the attribute, the default fetch graph of the target entity
> is fetched. If a subgraph is specified for the attribute, any attributes
> of the target entity that are not further specified are treated according
> to their fetch type; attributes that are specified by the subgraph are also
> fetched; and the rules of this section recursively apply.
>
> If the attribute is a one-to-many or many-to-many relationship, and
> the attribute is specified in an attribute node, but a subgraph is not
> specified, the collection will be fetched and the default fetch graphs of
> the referenced entities will be fetched. If a subgraph is specified for
> the attribute, any entities in the collection will be treated according to
> their fetch type; attributes that are specified by the subgraph are also
> fetched; and the rules of this section recursively apply.
>
> If a collection-valued attribute is a map, keys that are basic or
> embeddable types will be fetched when the map is fetched; entity map key
> attributes will be fetched according to their fetch type and, if a key
> subgraph is specified, additional entity attributes are fetched as
> specified in the subgraph; and the rules of this section recursively apply.
>
> So using the following entity graph:
>
> @NamedEntityGraph(
> )
>
> used to load a Phonenumber only the id and the FKs would be retrieved.
> The requirements attribute would not be loaded but would be lazy.
>
> When using the following entity graph:
> @NamedEntityGraph(
> attributeNodes={
> @NamedAttributeNode("projects"),
> }
> )
>
> loading an Employee the PKs and FKs would be retrieved and the
> “projects” attribute would be eagerly loaded.
>
> EntityManager API
> public interface EntityManager {
>
> /**
> * Copy the provided entity graph using the EntityGraph as a
> template to
> specify
> * the attributes that will be copied. Attributes not included in
> the entity graph will not be copied.
> *
> * @param entity
> * entity instance
> * @param EntityGraph
> * the entity graph template for applying copy.
> * @throws IllegalArgumentException
> * if the instance is not an entity or the EntityGraph
> root is
> * not the same class as the entity.
> */
> public void copy(Object entity, EntityGraph entityGraph,
> Map<String, Object> properties);
> ...
>
> /**
> * Merge the state of the given entity into the current persistence
> context
> * using the EntityGraph as a template for applying the merge
> operation.
> *
> *
> * @param entity
> * entity instance
> * @param EntityGraph
> * the entity graph template for applying merge.
> * @return the managed instance that the state was merged to
> * @throws IllegalArgumentException
> * if instance is not an entity, is a removed entity or
> the root
> * of the EntityGraph is not of the same type as the
> entity
> * @throws TransactionRequiredException
> * if there is no transaction when invoked on a
> * container-managed entity manager of that is of type
> * <code>PersistenceContextType.TRANSACTION</code>
> */
> public <T> T merge(T entity, EntityGraph entityGraph, Map<String,
> Object> properties);
> ...etc
> }
> *
> Merge*
> When using an entity graph in combination with the “merge” operation
> any listed attribute node will be merged and any unlisted attribute node
> will not be merged, this includes @Basic mappings. Any attribute that
> references a Map is considered to include both the key and the value. If
> the attribute node references a sub-graph or map key sub-graph for the
> relationship target then the merge will operate on that target object as
> well with only those attributes referenced in the sub-graph being merged
> and this will apply recursively.
>
> For example with the merge operation applied with the following entity
> graph :
>
> @NamedEntityGraph(
> attributeNodes={
> @NamedAttributeNode(“name”),
> @NamedAttributeNode(
> value="projects",
> subGraph=”projects”
> ),
> @NamedAttributeNode("phoneNumbers"),
> },
> subGraphs={
> @NamedSubGraph(
> name=”projects”,
> attributeNodes={
> @NamedAttributeNode("requirements")
> }
> )
> }
> )
>
> Only the name, projects and phoneNumbers attributes of the Employee
> will be merged. The merge will be applied to the projects but only the
> requirements attribute of the Project will be merged and the merge will not
> be applied to the Requirement target. The PhoneNumber target will not be
> merged.
> *
> Copy*
> A new operation “copy” is being introduced. This operation is
> intended to be used when a user wishes to disconnect a graph of entities
> from a larger graph. When using an entity graph in combination with the
> “copy” operation a copy of the provided entity is created and the
> attributes of the copied entity are populated based on the attributes
> listed in the entity graph. If an attribute node for an attribute is
> present then the attribute will be copied. If the attribute node
> represents an attribute that has a managed type as the target, element or
> key type then that target instance is copied as well and the copy is set in
> the new tree. If a sub-graph is defined for the value or key then any
> attributes corresponding to the attribute nodes within the sub-graph will
> be copied as above. If no sub-graph is defined for the attribute node then
> no attributes of the target are copied.
>
> For example with the copy operation applied with the following entity
> graph :
>
> @NamedEntityGraph(
> attributeNodes={
> @NamedAttributeNode(“name”),
> @NamedAttributeNode(
> value="projects",
> subGraph=”projects”
> ),
> @NamedAttributeNode("phoneNumbers"),
> },
> subGraphs={
> @NamedSubGraph(
> name=”projects”,
> attributeNodes={
> @NamedAttributeNode("requirements")
> }
> )
> }
> )
>
> When applied to an Employee instance a new copy of the Employee will
> be created and the “name” , “phoneNumbers” and “projects” attributes will
> be copied over. For each PhoneNumber in the phoneNumbers list a new copy
> of the PhoneNumber will be created and used but no attributes will be
> copied. For each Project in the projects list a new copy of the Project
> will be created and used and only the requirements attribute will be
> copied. For each Requirement in the requirements list a new copy of the
> Requirement will be created but no attributes will be copied.
>
>
>




graycol.gif
(image/gif attachment: graycol.gif)