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
> asFetchType.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.
>