users@jpa-spec.java.net

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

From: Steve Ebersole <steve.ebersole_at_redhat.com>
Date: Thu, 29 Nov 2012 08:47:29 -0600

+1

In all other areas the spec calls out "partial loading" as optional.
When I read this new proposal I walked away with the same feeling of a
seeming disconnect in that same regard; that the proposal was trying to
make partial loading a mandate on providers.

On Thu 29 Nov 2012 07:08:51 AM CST, Christian von Kutzleben wrote:
> Hi Gordon,
>
> On Tue, Nov 27, 2012 at 10:20 PM, Gordon Yorke
> <gordon.yorke_at_oracle.com <mailto:gordon.yorke_at_oracle.com>> wrote:
>
> Attributes other than primary key attributes are not fetched
> unless the attribute is specified.
>
>
> This reads a bit like that the non-specified attributes must not be
> loaded, in difference to the FetchType.LAZY
> semantics, which is "need not be loaded".
>
> I would prefer to have this aligned (maybe that was even the
> intention?) with the FetchType.LAZY semantics, as
> in our implementation we do always load full objects, and never load
> objects partially (i.e. only a subset of attributes)
>
> Christian
>
> On Tue, Nov 27, 2012 at 10:20 PM, Gordon Yorke
> <gordon.yorke_at_oracle.com <mailto:gordon.yorke_at_oracle.com>> 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.
>
>
>
>
> --
> Christian von Kutzleben
> Chief Engineer | Versant GmbH
> (T) +49 40 60990-0
> (F) +49 40 60990-113
> (E) cvkutzleben_at_versant.com <mailto:cromberg_at_versant.com>
> www.versant.com <http://www.versant.com> | www.db4o.com
> <http://www.db4o.com>
>
> --
> Versant
> GmbH is incorporated in Germany. Company registration number: HRB
> 54723, Amtsgericht Hamburg. Registered Office: Halenreie 42, 22359
> Hamburg, Germany. Geschäftsführer: Bernhard Wöbker, Volker John
>
> CONFIDENTIALITY
> NOTICE: This e-mail message, including any attachments, is for the sole
> use of the intended recipient(s) and may contain confidential or
> proprietary information. Any unauthorized review, use, disclosure or
> distribution is prohibited. If you are not the intended recipient,
> immediately contact the sender by reply e-mail and destroy all copies of
> the original message.
>