jsr338-experts@jpa-spec.java.net

[jsr338-experts] Re: Entity Graphs

From: Gordon Yorke <gordon.yorke_at_oracle.com>
Date: Thu, 31 Jan 2013 13:26:35 -0500

> I understand that EntityGraph<Account>.getAttributeNodes() above
> returning *all* AttributeNodes for the entire graph would be badness.
absolutely.

On 31/01/2013 1:11 PM, Steve Ebersole wrote:
> I get that part. I would assume you can only get the AttributeNodes
> relative to the Graph that contains it.
>
> So if I have:
>
> @Entity public class Account {
> @Id Long id;
> String referenceNumber;
> @ManyToOne Customer customer;
> ...
> }
>
> @Entity public class Customer {
> @Id Long id;
> String name;
> @ManyToOne Address billingAddress;
> ...
> }
>
> @Entity public class Address {
> ...
> }
>
> If I wanted to get a graph of Account+Customer+(billing)Address you
> would do:
>
> EntityGraph<Account> accountGraph = em.createEntityGraph(
> Account.class );
> accountGraph.addAtributeNodes( Account_.referenceNumber );
> Subgraph<Customer> customerGraph = accountGraph.addSubgraph(
> Account_.customer );
> customerGraph.addAttributeNodes( Customer_.name );
> customerGraph.addSubgraph( Customer_.billngAddress );
> // though as I understand it calling addAttributeNodes(
> Customer_.billngAddress ) would be the same :/
>
>
> So the question is all in the proposed API for understanding an
> EntityGraph. In the current proposal (public review draft), as I
> understood it you'd end up with EntityGraph<Account> returning 2
> AttributeNodes from getAttributeNodes():
> 1) AttributeNode<String>(referenceNumber)
> 2) Subgraph<Customer>(customer)
>
> In turn, Subgraph<Customer>(customer) would return 2 AtributeNodes
> from its getAttributeNodes():
> 1) AttributeNode<String>(name)
> 2) Subgraph<Address>(billingAddress)
>
> I understand that EntityGraph<Account>.getAttributeNodes() above
> returning *all* AttributeNodes for the entire graph would be badness.
>
>
> So now in the new proposal, if I understand correctly, we'd instead
> have EntityGraph<Account> returning 2 AttributeNodes from
> getAttributeNodes() like so:
> 1) AttributeNode<String>(referenceNumber)
> 1.a) getSubgraphs() -> none
> 1.b) getKeySubgraphs() -> none
> 2) AttributeNode<Customer>(customer)
> 2.a) getSubgraphs() -> [Subgraph<Customer>]
> 2.b) getKeySubgraphs() -> none
>
> and so on.
>
> Tbh, its six-in-one to me. They each give you the same information.
> Yes, in one you need to do an explicit type check which is always nice
> to avoid.
>
> And still, I am not getting how you possibly end up with multiple "key
> subgraphs" for a given AttributeNode. That part makes no sense to
> me. In my understanding the Subgraph there would refer to the Map key
> of the Map-valued collection represented by the containing
> AttributeNode. How can a Map have multiple keys?
>
>
>
>
> On Thu 31 Jan 2013 11:36:03 AM CST, Linda DeMichiel wrote:
>> Hi Steve,
>>
>> I don't know exactly what Gordon had in mind when he wrote this, but
>> here is the problem that I see.
>>
>> Since an entity graph may involve many entities, there may be
>> multiple entities that have the same attribute (i.e., attribute
>> name/type combination). If you just retrieve all the subgraphs in
>> an entity graph, that doesn't give you enough information as to
>> what subgraph corresponds to which entity's attribute.
>>
>> Traversing the graph downwards (and recursively) from the root, via
>> the attribute nodes for any given entity allows the structure
>> of the graph to be discerned.
>>
>> HTH,
>>
>> -Linda
>>
>>
>> On 1/31/2013 6:10 AM, Steve Ebersole wrote:
>>> Sorry for being dense about this (but honestly I have asked others in
>>> the group and they are just as confused by this
>>> graph stuff)...
>>>
>>> Can you explain the "multiple key subgraphs and multiple subgraphs
>>> can exist for any attribute" part?
>>>
>>> An attribute would be something like the "customer" attribute on an
>>> Account entity. So we'd have EntityGraph<Account>,
>>> with AttributeNode<Customer> as part of that EntityGraph<Account>'s
>>> getAttributeNodes() collection. The mere presence of
>>> AttributeNode<Customer> would indicate that Account.customer is
>>> supposed to be fetched, yes?
>>>
>>> As I understood it from yesterday's replies from yourself and Linda
>>> the intent in the above case would be that
>>> Account.customer could be represented by either
>>> AttributeNode<Customer> or Subgraph<Customer> depending on whether the
>>> user intended to further qualify the fetch graph "below" Customer.
>>> Your new suggestion seems to indicate a fundamentally
>>> different view of this. Now, an attribute reference is aways going to
>>> be an AttributeNode. Under that we'd just have
>>> further possible qualifications of that fetch subgraph. Yes? If so,
>>> OK I can buy that as an improvement (the old deal
>>> was VERY counter-intuitive IMHO).
>>>
>>> Going back to the quote "multiple key subgraphs and multiple
>>> subgraphs can exist for any attribute", especially
>>> confusing to me is the "multiple key subgraphs" portion. How can an
>>> attribute (a representation of the Map attribute)
>>> have multiple subgraphs *at that level* representing the map key?
>>> There is something fundamental I am missing here...
>>>
>>>
>>> On 01/30/2013 02:51 PM, Gordon Yorke wrote:
>>>> The issue is multiple key subgraphs and multiple subgraphs can exist
>>>> for any attribute. If we do not organize the
>>>> subgraphs under an AttributeNode just like the annotations are
>>>> structured it gets very difficult to convey the
>>>> contents of an entity graph to a user in a manageable way. if we
>>>> were to add getKeySubgraphs to EntityManager the
>>>> return would have to be List<Map<Class,Subgraph>> at the least. Any
>>>> other structure(ie. List<Subgraph>) and the user
>>>> would need to organize the results to make the information
>>>> meaningful. Also if get*Subgraphs methods were added to the
>>>> EntityGraph the user would need to check all three collections to
>>>> determine what attributes were present in the entity
>>>> graph.
>>>> --Gordon
>>>>
>>>> On 30/01/2013 3:02 PM, Steve Ebersole wrote:
>>>>> Oh, I misunderstood. I thought you were suggesting that
>>>>> getSubgraphs and getKeySubgraphs would become part of
>>>>> EntityGraph and Subgraph. Putting them on AttributeNode does not
>>>>> make sense to me. At least not as I was
>>>>> understanding the intention/breakdown between AttributeNode and
>>>>> Subgraph from your and Linda's replies from yesterday.
>>>>>
>>>>>
>>>>> On Wed 30 Jan 2013 01:29:17 PM CST, Gordon Yorke wrote:
>>>>>> The original plan was to simplify the interfaces and eliminate the
>>>>>> AttributeNode as an artifact the user needed, however as the
>>>>>> structure
>>>>>> of the Subgraph became more complex to support the more complex
>>>>>> scenarios I no longer think this is an option as we should support
>>>>>> inspection in the future. I am proposing that Subgraph interface no
>>>>>> longer extends from AttributeNode and that AttributeNode would be
>>>>>> updated to be :
>>>>>> public interface AttributeNode<T> {
>>>>>>
>>>>>> /**
>>>>>> * Return the name of the attribute corresponding to the
>>>>>> * attribute node.
>>>>>> * @return name of the attribute
>>>>>> */
>>>>>> public String getAttributeName();
>>>>>>
>>>>>> /**
>>>>>> * Return the Map<Class, Subgraph> of Subgraphs associated with
>>>>>> this AttributeNode
>>>>>> * @return Map of Subgraphs associated with this AttribureNode
>>>>>> */
>>>>>> public Map<Class, Subgraph> getSubgraphs();
>>>>>>
>>>>>> /**
>>>>>> * Return the Map<Class, Subgraph> of Subgraphs associated with
>>>>>> this AttributeNode's map key
>>>>>> * @return Map of Subgraphs associated with this AttribureNode's
>>>>>> map key
>>>>>> */
>>>>>> public Map<Class, Subgraph> getKeySubgraphs();
>>>>>> }
>>>>>>
>>>>>> This would allow for easier inspection of the EntityGraph and easily
>>>>>> allow the user to differentiate between map key subgraphs and
>>>>>> element
>>>>>> subgraphs.
>>>>>> --Gordon
>>>>>>
>>>>>> On 30/01/2013 12:35 PM, Linda DeMichiel wrote:
>>>>>>> Hi Gordon,
>>>>>>>
>>>>>>> Could you propose the specific methods that you think should be
>>>>>>> added
>>>>>>> in this release?
>>>>>>>
>>>>>>> thanks,
>>>>>>>
>>>>>>> -Linda
>>>>>>>
>>>>>>>
>>>>>>> On 1/30/2013 6:29 AM, Gordon Yorke wrote:
>>>>>>>> Yes, they should although it may be easier to support more
>>>>>>>> inspection in the future if AttributeNode.getSubgraps()
>>>>>>>> AttributeNode.getKeySubgraphs() were to exist or planned to exist.
>>>>>>>> The alternate pattern that will be needed of
>>>>>>>> isKeySubgraph() is not a great pattern. I think we should add this
>>>>>>>> simple methods to this release if possible.
>>>>>>>> --Gordon
>>>>>>>>
>>>>>>>>
>>>>>>>> On 29/01/2013 5:42 PM, Steve Ebersole wrote:
>>>>>>>>> Also related... Do EntityGraph.getAttributeNodes /
>>>>>>>>> Subgraph.getAttributeNodes return Subgraphs in the
>>>>>>>>> AttributeNode list?
>>>>>>>>>
>>>>>>>>> On Tue 29 Jan 2013 04:14:13 PM CST, Steve Ebersole wrote:
>>>>>>>>>> What is the proposed behavior of EntityGraph or Subgraph when
>>>>>>>>>> addAttributeNodes is called with non-basic attribute types (a
>>>>>>>>>> ManyToOne for example)? Is that considered an exception
>>>>>>>>>> condition?
>>>>>>>>>> And if so, what exception (IllegalArgumentException)? Or do
>>>>>>>>>> providers
>>>>>>>>>> simply interpret it as a call to addSubgraph?
>>>>>>>>>>
>>>>>>>>>> Also, a minor edit to report in the spec, at least as of the
>>>>>>>>>> Public
>>>>>>>>>> Review Draft. In the definition of the NamedEntityGraph
>>>>>>>>>> annotation,
>>>>>>>>>> the type of subclassSubgraphs is defined as NamedSubGraph[]
>>>>>>>>>> rather
>>>>>>>>>> than NamedSubgraph[]
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> On Sun 09 Dec 2012 05:04:55 PM CST, Linda DeMichiel wrote:
>>>>>>>>>>> I've spec'd out a more detailed version of the proposal. Please
>>>>>>>>>>> review and comment.
>>>>>>>>>>>
>>>>>>>>>>> thanks,
>>>>>>>>>>>
>>>>>>>>>>> -Linda
>>>>>>>>>>>
>>>>>>>>>>> -------------------------------
>>>>>>>>>>>
>>>>>>>>>>> Section: Entity Graphs
>>>>>>>>>>>
>>>>>>>>>>> An entity graph is a template that is defined in the form of
>>>>>>>>>>> metadata
>>>>>>>>>>> or an object created by the dynamic EntityGraph API and that
>>>>>>>>>>> captures
>>>>>>>>>>> the path and boundaries for an operation or query.
>>>>>>>>>>>
>>>>>>>>>>> Entity graphs are used in the specification of "fetch plans"
>>>>>>>>>>> for
>>>>>>>>>>> query or find operations and as specifications for the
>>>>>>>>>>> boundaries
>>>>>>>>>>> of merge or copy operations.
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> Subsection: Use of Entity Graphs in find and query operations
>>>>>>>>>>>
>>>>>>>>>>> An entity graph can be used with the find operation or as a
>>>>>>>>>>> query
>>>>>>>>>>> hint to override or augment FetchType semantics.
>>>>>>>>>>>
>>>>>>>>>>> The standard properties javax.persistence.fetchgraph and
>>>>>>>>>>> javax.persistence.loadgraph are used to specify such graphs to
>>>>>>>>>>> queries
>>>>>>>>>>> and find operations.
>>>>>>>>>>>
>>>>>>>>>>> The default fetch graph for an entity or embeddable is
>>>>>>>>>>> defined to
>>>>>>>>>>> consist of the transitive closure of all of its attributes
>>>>>>>>>>> that are
>>>>>>>>>>> specified as FetchType.EAGER (or defaulted as such).
>>>>>>>>>>>
>>>>>>>>>>> The persistence provider is permitted to fetch additional
>>>>>>>>>>> entity
>>>>>>>>>>> state
>>>>>>>>>>> beyond that specified by a fetch graph or load graph. It is
>>>>>>>>>>> required,
>>>>>>>>>>> however, that the persistence provider fetch all state
>>>>>>>>>>> specified
>>>>>>>>>>> by the
>>>>>>>>>>> fetch or load graph.
>>>>>>>>>>>
>>>>>>>>>>> Subsectionsection: Fetch graph semantics
>>>>>>>>>>>
>>>>>>>>>>> When the javax.persistence.fetchgraph property is used to
>>>>>>>>>>> specify an
>>>>>>>>>>> entity graph, attributes that are specified by attribute
>>>>>>>>>>> nodes of
>>>>>>>>>>> the
>>>>>>>>>>> entity graph are treated as FetchType.EAGER and attributes
>>>>>>>>>>> that are
>>>>>>>>>>> not specified are treated as FetchType.LAZY. The primary key
>>>>>>>>>>> and
>>>>>>>>>>> version attributes of an entity are always retrieved, even if
>>>>>>>>>>> not
>>>>>>>>>>> specified by the fetch graph.
>>>>>>>>>>>
>>>>>>>>>>> The following rules apply, depending on attribute type. The
>>>>>>>>>>> rules of
>>>>>>>>>>> this section are applied recursively.
>>>>>>>>>>>
>>>>>>>>>>> A primary key or version attribute never needs to be
>>>>>>>>>>> specified in an
>>>>>>>>>>> attribute node of a fetch graph. (This applies to composite
>>>>>>>>>>> primary
>>>>>>>>>>> keys as well, including embedded id primary keys.) When an
>>>>>>>>>>> entity is
>>>>>>>>>>> fetched, its primary key and version attributes are always
>>>>>>>>>>> fetched.
>>>>>>>>>>> It is not incorrect, however, to specify primary key
>>>>>>>>>>> attributes or
>>>>>>>>>>> version attributes.
>>>>>>>>>>>
>>>>>>>>>>> Attributes other than primary key and version attributes are
>>>>>>>>>>> assumed
>>>>>>>>>>> not to be fetched unless the attribute is specified. The
>>>>>>>>>>> following
>>>>>>>>>>> rules apply to the specification of 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, the attributes
>>>>>>>>>>> of the
>>>>>>>>>>> embeddable are fetched according to their specification in the
>>>>>>>>>>> corresponding subgraph.
>>>>>>>>>>>
>>>>>>>>>>> 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.
>>>>>>>>>>>
>>>>>>>>>>> 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.
>>>>>>>>>>>
>>>>>>>>>>> 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.
>>>>>>>>>>>
>>>>>>>>>>> If the key of a map which has been specified in an attribute
>>>>>>>>>>> node
>>>>>>>>>>> is a
>>>>>>>>>>> basic type, it will always be fetched. 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
>>>>>>>>>>> the
>>>>>>>>>>> key
>>>>>>>>>>> of the map is an entity, and 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.
>>>>>>>>>>>
>>>>>>>>>>> Example:
>>>>>>>>>>>
>>>>>>>>>>> @NamedEntityGraph
>>>>>>>>>>> @Entity
>>>>>>>>>>> public class Phonenumber{
>>>>>>>>>>> @Id
>>>>>>>>>>> protected String number;
>>>>>>>>>>>
>>>>>>>>>>> protected PhoneTypeEnum type;
>>>>>>>>>>> ...
>>>>>>>>>>> }
>>>>>>>>>>>
>>>>>>>>>>> In this example, only the number attribute would be eagerly
>>>>>>>>>>> fetched.
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> Example:
>>>>>>>>>>>
>>>>>>>>>>> @NamedEntityGraph(
>>>>>>>>>>> attributeNodes={
>>>>>>>>>>> @NamedAttributeNode("projects")
>>>>>>>>>>> }
>>>>>>>>>>> )
>>>>>>>>>>> @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;
>>>>>>>>>>>
>>>>>>>>>>> String name;
>>>>>>>>>>>
>>>>>>>>>>> @OneToOne(fetch=FetchType.EAGER)
>>>>>>>>>>> protected Requirements doc;
>>>>>>>>>>> ...
>>>>>>>>>>> }
>>>>>>>>>>>
>>>>>>>>>>> @Entity
>>>>>>>>>>> public class LargeProject extends Project{
>>>>>>>>>>>
>>>>>>>>>>> @OneToOne(fetch=FetchType.LAZY)
>>>>>>>>>>> protected Employee approver;
>>>>>>>>>>> ...
>>>>>>>>>>> }
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> @Entity
>>>>>>>>>>> public class Requirements{
>>>>>>>>>>> @Id
>>>>>>>>>>> protected long id;
>>>>>>>>>>>
>>>>>>>>>>> @Lob
>>>>>>>>>>> protected String description;
>>>>>>>>>>>
>>>>>>>>>>> @OneToOne(fetch=FetchType.LAZY)
>>>>>>>>>>> protected Approval approval
>>>>>>>>>>> ...
>>>>>>>>>>> }
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> In the above example, the Employee entity's primary key will be
>>>>>>>>>>> fetched as well as the related project instances, whose default
>>>>>>>>>>> fetch
>>>>>>>>>>> graph (id, name, and doc attributes) will be fetched. The
>>>>>>>>>>> related
>>>>>>>>>>> Requirements object will be fetched according to its default
>>>>>>>>>>> fetch
>>>>>>>>>>> graph.
>>>>>>>>>>>
>>>>>>>>>>> If the approver attribute of LargeProject were
>>>>>>>>>>> FetchType.EAGER, and
>>>>>>>>>>> if any of the projects were instances of LargeProject, their
>>>>>>>>>>> approver
>>>>>>>>>>> attributes would also be fetched. Since the type of the
>>>>>>>>>>> approver
>>>>>>>>>>> attribute is Employee, the approver's default fetch graph
>>>>>>>>>>> (id, name,
>>>>>>>>>>> and employeeNumber attributes) would also be fetched.
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> Subsubsection: Load graph semantics:
>>>>>>>>>>>
>>>>>>>>>>> When the javax.persistence.loadgraph property is used to
>>>>>>>>>>> specify an
>>>>>>>>>>> entity graph, attributes that are specified by attribute
>>>>>>>>>>> nodes of
>>>>>>>>>>> the
>>>>>>>>>>> entity graph are treated as FetchType.EAGER and attributes
>>>>>>>>>>> that are
>>>>>>>>>>> not specified are treated according to their specified or
>>>>>>>>>>> default
>>>>>>>>>>> FetchType. The primary key and version attributes of an
>>>>>>>>>>> entity are
>>>>>>>>>>> always retrieved.
>>>>>>>>>>>
>>>>>>>>>>> The following rules apply. The rules of this section are
>>>>>>>>>>> applied
>>>>>>>>>>> recursively.
>>>>>>>>>>>
>>>>>>>>>>> A primary key or version attribute never needs to be
>>>>>>>>>>> specified in an
>>>>>>>>>>> attribute node of a load graph. (This applies to composite
>>>>>>>>>>> primary
>>>>>>>>>>> keys as well, including embedded id primary keys.) When an
>>>>>>>>>>> entity is
>>>>>>>>>>> fetched, its primary key and version attributes are always
>>>>>>>>>>> fetched.
>>>>>>>>>>> It is not incorrect, however, to specify primary key
>>>>>>>>>>> attributes or
>>>>>>>>>>> version attributes.
>>>>>>>>>>>
>>>>>>>>>>> If the attribute is an embedded attribute, and the attribute is
>>>>>>>>>>> specified in an attribute node, the default fetch graph for the
>>>>>>>>>>> embeddable is fetched. If a subgraph is specified for the
>>>>>>>>>>> attribute,
>>>>>>>>>>> attributes that are specified by the subgraph are also fetched.
>>>>>>>>>>>
>>>>>>>>>>> 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, the element
>>>>>>>>>>> collection
>>>>>>>>>>> together with the default fetch graph of its embeddable
>>>>>>>>>>> elements is
>>>>>>>>>>> fetched. If a subgraph is specified for the attribute,
>>>>>>>>>>> attributes
>>>>>>>>>>> that are specified by the subgraph are also fetched.
>>>>>>>>>>>
>>>>>>>>>>> If the attribute is a one-to-one or many-to-one relationship,
>>>>>>>>>>> and
>>>>>>>>>>> the
>>>>>>>>>>> attribute is specified in an attribute node, the default
>>>>>>>>>>> fetch graph
>>>>>>>>>>> of the target entity is fetched. If a subgraph is specified
>>>>>>>>>>> for the
>>>>>>>>>>> attribute, attributes that are specified by the subgraph are
>>>>>>>>>>> also
>>>>>>>>>>> fetched.
>>>>>>>>>>>
>>>>>>>>>>> If the attribute is a one-to-many or many-to-many
>>>>>>>>>>> relationship, and
>>>>>>>>>>> the attribute is specified in an attribute node, 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,
>>>>>>>>>>> attributes that are specified by the subgraph are also fetched.
>>>>>>>>>>>
>>>>>>>>>>> If a collection-valued attribute is a map, and the map-valued
>>>>>>>>>>> attribute is specified in an attribute node, keys that are
>>>>>>>>>>> basic or
>>>>>>>>>>> embeddable types will be fetched when the map is fetched;
>>>>>>>>>>> entity map
>>>>>>>>>>> key attributes will be fetched according to the default fetch
>>>>>>>>>>> graph
>>>>>>>>>>> and, if a key subgraph is specified, additional entity
>>>>>>>>>>> attributes
>>>>>>>>>>> are
>>>>>>>>>>> fetched as specified in the subgraph.
>>>>>>>>>>>
>>>>>>>>>>> Example:
>>>>>>>>>>>
>>>>>>>>>>> @NamedEntityGraph
>>>>>>>>>>> @Entity
>>>>>>>>>>> public class Phonenumber{
>>>>>>>>>>> @Id
>>>>>>>>>>> protected String number;
>>>>>>>>>>>
>>>>>>>>>>> protected PhoneTypeEnum type;
>>>>>>>>>>> ...
>>>>>>>>>>> }
>>>>>>>>>>>
>>>>>>>>>>> In the above example, the number and type attributes are
>>>>>>>>>>> loaded.
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> Example:
>>>>>>>>>>>
>>>>>>>>>>> @NamedEntityGraph(
>>>>>>>>>>> attributeNodes={
>>>>>>>>>>> @NamedAttributeNode("projects")
>>>>>>>>>>> }
>>>>>>>>>>> )
>>>>>>>>>>> @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;
>>>>>>>>>>>
>>>>>>>>>>> String name;
>>>>>>>>>>>
>>>>>>>>>>> @OneToOne(fetch=FetchType.EAGER)
>>>>>>>>>>> protected Requirements doc;
>>>>>>>>>>> ...
>>>>>>>>>>> }
>>>>>>>>>>>
>>>>>>>>>>> @Entity
>>>>>>>>>>> public class LargeProject extends Project{
>>>>>>>>>>>
>>>>>>>>>>> @OneToOne(fetch=FetchType.LAZY)
>>>>>>>>>>> protected Employee approver;
>>>>>>>>>>> ...
>>>>>>>>>>> }
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> @Entity
>>>>>>>>>>> public class Requirements{
>>>>>>>>>>> @Id
>>>>>>>>>>> protected long id;
>>>>>>>>>>>
>>>>>>>>>>> @Lob
>>>>>>>>>>> protected String description;
>>>>>>>>>>>
>>>>>>>>>>> @OneToOne(fetch=FetchType.LAZY)
>>>>>>>>>>> protected Approval approval
>>>>>>>>>>> ...
>>>>>>>>>>> }
>>>>>>>>>>>
>>>>>>>>>>> In the above example, the default fetch graph (id, name, and
>>>>>>>>>>> employeeNumber) of Employee is loaded. The default fetch
>>>>>>>>>>> graphs of
>>>>>>>>>>> the related Project instances (id, name, and doc attributes)
>>>>>>>>>>> and
>>>>>>>>>>> their
>>>>>>>>>>> Requirements instances (id and description attributes) are also
>>>>>>>>>>> loaded.
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> Subsection: Merge graph semantics
>>>>>>>>>>>
>>>>>>>>>>> An entity graph may be used as a "merge graph" and passed as an
>>>>>>>>>>> argument to the merge method.
>>>>>>>>>>>
>>>>>>>>>>> The following semantics apply to entity graphs that are used as
>>>>>>>>>>> merge
>>>>>>>>>>> graphs.
>>>>>>>>>>>
>>>>>>>>>>> A merge graph attribute node specified within an entity
>>>>>>>>>>> graph or
>>>>>>>>>>> subgraph specifies how an attribute is to be merged. Primary
>>>>>>>>>>> key and
>>>>>>>>>>> version attributes do not need to be specified in the merge
>>>>>>>>>>> graph. If
>>>>>>>>>>> other attributes are not specified, they are not merged. Note
>>>>>>>>>>> that
>>>>>>>>>>> cascade=MERGE specifications are ignored.
>>>>>>>>>>>
>>>>>>>>>>> The persistence provider must observe the scope and
>>>>>>>>>>> boundaries of a
>>>>>>>>>>> merge graph specification exactly.
>>>>>>>>>>>
>>>>>>>>>>> The following additional rules apply for attributes that are
>>>>>>>>>>> specified in attribute nodes. These rules are applied
>>>>>>>>>>> recursively.
>>>>>>>>>>>
>>>>>>>>>>> If the attribute is an embedded attribute and a subgraph is not
>>>>>>>>>>> specified for the attribute, the embedded attribute is merged
>>>>>>>>>>> but
>>>>>>>>>>> the
>>>>>>>>>>> attributes of the embeddable are not merged. If a subgraph is
>>>>>>>>>>> specified for the attribute, the attributes of the embeddable
>>>>>>>>>>> are
>>>>>>>>>>> merged according to their specification in the corresponding
>>>>>>>>>>> subgraph.
>>>>>>>>>>>
>>>>>>>>>>> If the attribute is an element collection of basic type, the
>>>>>>>>>>> element
>>>>>>>>>>> collection is merged. The values in the element collection are
>>>>>>>>>>> replaced.
>>>>>>>>>>>
>>>>>>>>>>> If the attribute is an element collection of embeddables and a
>>>>>>>>>>> subgraph is not specified for the attribute, the element
>>>>>>>>>>> collection is
>>>>>>>>>>> merged. The values in the element collection are replaced and
>>>>>>>>>>> all
>>>>>>>>>>> attributes of the embeddables are included. If a subgraph is
>>>>>>>>>>> specified for the attribute, the values in the element
>>>>>>>>>>> collection
>>>>>>>>>>> are
>>>>>>>>>>> replaced and all attributes of the embeddables are included,
>>>>>>>>>>> and the
>>>>>>>>>>> attributes specified in the subgraph are processed according
>>>>>>>>>>> to the
>>>>>>>>>>> subgraph specification.
>>>>>>>>>>>
>>>>>>>>>>> If the attribute is a one-to-one or many-to-one relationship
>>>>>>>>>>> and a
>>>>>>>>>>> subgraph is not specified for the attribute, the attribute is
>>>>>>>>>>> merged,
>>>>>>>>>>> but the attributes of the target entity are not merged. If a
>>>>>>>>>>> subgraph
>>>>>>>>>>> is specified for the attribute, the attributes of the target
>>>>>>>>>>> entity
>>>>>>>>>>> will be merged according to the corresponding subgraph
>>>>>>>>>>> specification.
>>>>>>>>>>>
>>>>>>>>>>> If the attribute is a one-to-many or many-to-many
>>>>>>>>>>> relationship and a
>>>>>>>>>>> subgraph is not specified for the attribute, the attribute is
>>>>>>>>>>> merged,
>>>>>>>>>>> but the attributes of the target entity are not merged. If a
>>>>>>>>>>> subgraph
>>>>>>>>>>> is specified for the attribute, the entities in the collection
>>>>>>>>>>> will be
>>>>>>>>>>> merged according to the corresponding subgraph specification.
>>>>>>>>>>>
>>>>>>>>>>> In both of the two relationship cases above, note that if a new
>>>>>>>>>>> entity (entity in the "new" state) was added to the
>>>>>>>>>>> relationship and
>>>>>>>>>>> only a subset of its attributes is specified in the subgraph,
>>>>>>>>>>> only
>>>>>>>>>>> those specified attributes are copied.
>>>>>>>>>>>
>>>>>>>>>>> If the attribute is a map, the map key will be merged. If the
>>>>>>>>>>> map
>>>>>>>>>>> key
>>>>>>>>>>> is an embeddable, all attributes of the embeddable are
>>>>>>>>>>> included. If
>>>>>>>>>>> the map key is an entity, the attribute is merged, but the
>>>>>>>>>>> attributes
>>>>>>>>>>> of the target entity are not merged. If a subgraph is
>>>>>>>>>>> specified for
>>>>>>>>>>> the attribute, the target entity is merged according to the
>>>>>>>>>>> corresponding
>>>>>>>>>>> subgraph specification.
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> Example:
>>>>>>>>>>>
>>>>>>>>>>> @NamedEntityGraph(
>>>>>>>>>>> attributeNodes={
>>>>>>>>>>> @NamedAttributeNode("name"),
>>>>>>>>>>> @NamedAttributeNode(
>>>>>>>>>>> value="projects",
>>>>>>>>>>> subGraph="projects"
>>>>>>>>>>> ),
>>>>>>>>>>> @NamedAttributeNode("phoneNumbers"),
>>>>>>>>>>> },
>>>>>>>>>>> subGraphs={
>>>>>>>>>>> @NamedSubGraph(
>>>>>>>>>>> name="projects",
>>>>>>>>>>> attributeNodes={
>>>>>>>>>>> @NamedAttributeNode("doc")
>>>>>>>>>>> }
>>>>>>>>>>> )
>>>>>>>>>>> }
>>>>>>>>>>> )
>>>>>>>>>>> @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
>>>>>>>>>>> public class Phonenumber{
>>>>>>>>>>> @Id
>>>>>>>>>>> protected String number;
>>>>>>>>>>>
>>>>>>>>>>> protected PhoneTypeEnum type;
>>>>>>>>>>> ...
>>>>>>>>>>> }
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> @Entity
>>>>>>>>>>> @Inheritance
>>>>>>>>>>> public class Project{
>>>>>>>>>>> @Id
>>>>>>>>>>> @GeneratedValue
>>>>>>>>>>> protected long id;
>>>>>>>>>>>
>>>>>>>>>>> String name;
>>>>>>>>>>>
>>>>>>>>>>> @OneToOne(fetch=FetchType.EAGER)
>>>>>>>>>>> protected Requirements doc;
>>>>>>>>>>> ...
>>>>>>>>>>> }
>>>>>>>>>>>
>>>>>>>>>>> In the above example, the name attribute and the projects and
>>>>>>>>>>> phoneNumbers
>>>>>>>>>>> collections will be merged. Within projects, only the doc
>>>>>>>>>>> attribute
>>>>>>>>>>> will
>>>>>>>>>>> be merged. No attributes of phoneNumbers will be merged.
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> Subsection: Copy graph semantics
>>>>>>>>>>>
>>>>>>>>>>> An entity graph may be used as a "copy graph" and passed as an
>>>>>>>>>>> argument to the copy method.
>>>>>>>>>>>
>>>>>>>>>>> The copy method is intended for use in disconnecting a graph of
>>>>>>>>>>> entities from a larger graph. When using an entity graph in
>>>>>>>>>>> combination with the copy operation, a copy of the entity is
>>>>>>>>>>> created
>>>>>>>>>>> and the attributes of the copied entity are populated based on
>>>>>>>>>>> copies
>>>>>>>>>>> of the attributes listed in the entity graph.
>>>>>>>>>>>
>>>>>>>>>>> The following semantics apply to entity graphs that are used
>>>>>>>>>>> as copy
>>>>>>>>>>> graphs.
>>>>>>>>>>>
>>>>>>>>>>> The persistence provider must observe the scope and
>>>>>>>>>>> boundaries of a
>>>>>>>>>>> copy graph specification exactly.
>>>>>>>>>>>
>>>>>>>>>>> OPEN ISSUE: If a copy graph specifies an attribute that has not
>>>>>>>>>>> yet been loaded, should it be loaded?
>>>>>>>>>>>
>>>>>>>>>>> The following rules apply to the specification of attributes.
>>>>>>>>>>> The
>>>>>>>>>>> rules of this section are applied recursively.
>>>>>>>>>>>
>>>>>>>>>>> Primary key and version attributes are always copied.
>>>>>>>>>>> Attributes are otherwise not copied unless they are specified.
>>>>>>>>>>>
>>>>>>>>>>> If the attribute is an embedded attribute and an attribute
>>>>>>>>>>> node is
>>>>>>>>>>> specified for the attribute but a subgraph is not specified
>>>>>>>>>>> for the
>>>>>>>>>>> attribute, a new instance of the embeddable is inserted into
>>>>>>>>>>> the
>>>>>>>>>>> resulting copy of the entity graph, but no state is copied.
>>>>>>>>>>> If a
>>>>>>>>>>> subgraph is specified for the attribute, the attributes of the
>>>>>>>>>>> embeddable are copied according to their specification in the
>>>>>>>>>>> corresponding subgraph.
>>>>>>>>>>>
>>>>>>>>>>> If the attribute is an element collection of basic type, the
>>>>>>>>>>> element
>>>>>>>>>>> collection and its contents are copied.
>>>>>>>>>>>
>>>>>>>>>>> If the attribute is an element collection of embeddables and an
>>>>>>>>>>> attribute node is specified for the attribute but a subgraph
>>>>>>>>>>> is not
>>>>>>>>>>> specified, a new collection is created and new embeddables
>>>>>>>>>>> instances
>>>>>>>>>>> are inserted into it, but no state is copied. If a subgraph is
>>>>>>>>>>> specified for the attribute, the embeddables are copied
>>>>>>>>>>> according to
>>>>>>>>>>> their specification in the subgraph.
>>>>>>>>>>>
>>>>>>>>>>> If the attribute is a one-to-one or many-to-one relationship
>>>>>>>>>>> and an
>>>>>>>>>>> attribute node is specified for the attribute, but a subgraph
>>>>>>>>>>> is not
>>>>>>>>>>> specified, a copy of the entity is created and inserted. Only
>>>>>>>>>>> the
>>>>>>>>>>> primary key and version attributes of the entity are copied.
>>>>>>>>>>> If a
>>>>>>>>>>> subgraph is specified for the attribute, a copy of the
>>>>>>>>>>> entity is
>>>>>>>>>>> created and inserted and the attributes of the target entity
>>>>>>>>>>> are
>>>>>>>>>>> copied according to the corresponding subgraph specification
>>>>>>>>>>> along
>>>>>>>>>>> with the primary key and version attributes.
>>>>>>>>>>>
>>>>>>>>>>> If the attribute is a one-to-many or many-to-many relationship
>>>>>>>>>>> and an
>>>>>>>>>>> attribute node is specified for the attribute, but a subgraph
>>>>>>>>>>> is not
>>>>>>>>>>> specified, a new collection is created and inserted, and copies
>>>>>>>>>>> of the
>>>>>>>>>>> referenced entities are created and inserted into the
>>>>>>>>>>> collection.
>>>>>>>>>>> Only the primary key and version attributes of these entities
>>>>>>>>>>> are
>>>>>>>>>>> copied. If a subgraph is specified for the attribute, the
>>>>>>>>>>> entities in
>>>>>>>>>>> the collection will be copied according to the corresponding
>>>>>>>>>>> subgraph
>>>>>>>>>>> specification along with the primary key and version
>>>>>>>>>>> attributes.
>>>>>>>>>>>
>>>>>>>>>>> If the attribute is a map and an attribute node has been
>>>>>>>>>>> specified for
>>>>>>>>>>> the attribute:
>>>>>>>>>>> if the map key attribute is a basic type, it is copied;
>>>>>>>>>>> if the map key attribute is an embedded attribute, a new
>>>>>>>>>>> instance
>>>>>>>>>>> of the
>>>>>>>>>>> embeddable is inserted but no state is copied;
>>>>>>>>>>> if the map key attribute is an entity, a copy of the entity is
>>>>>>>>>>> created,
>>>>>>>>>>> and only the primary key and version attributes of the entity
>>>>>>>>>>> are copied.
>>>>>>>>>>> If a subgraph is specified for the embeddable or entity, the
>>>>>>>>>>> attributes
>>>>>>>>>>> of the target are copied according to the corresponding map key
>>>>>>>>>>> subgraph specification.
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> Example:
>>>>>>>>>>>
>>>>>>>>>>> @NamedEntityGraph(
>>>>>>>>>>> attributeNodes={
>>>>>>>>>>> @NamedAttributeNode("name"),
>>>>>>>>>>> @NamedAttributeNode(
>>>>>>>>>>> value="projects",
>>>>>>>>>>> subGraph="projects"
>>>>>>>>>>> ),
>>>>>>>>>>> @NamedAttributeNode("phoneNumbers"),
>>>>>>>>>>> },
>>>>>>>>>>> subGraphs={
>>>>>>>>>>> @NamedSubGraph(
>>>>>>>>>>> name="projects",
>>>>>>>>>>> attributeNodes={
>>>>>>>>>>> @NamedAttributeNode("doc")
>>>>>>>>>>> }
>>>>>>>>>>> )
>>>>>>>>>>> }
>>>>>>>>>>> )
>>>>>>>>>>> @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
>>>>>>>>>>> public class Phonenumber{
>>>>>>>>>>> @Id
>>>>>>>>>>> protected String number;
>>>>>>>>>>>
>>>>>>>>>>> protected PhoneTypeEnum type;
>>>>>>>>>>> ...
>>>>>>>>>>> }
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> @Entity
>>>>>>>>>>> @Inheritance
>>>>>>>>>>> public class Project{
>>>>>>>>>>> @Id
>>>>>>>>>>> @GeneratedValue
>>>>>>>>>>> protected long id;
>>>>>>>>>>>
>>>>>>>>>>> String name;
>>>>>>>>>>>
>>>>>>>>>>> @OneToOne(fetch=FetchType.EAGER)
>>>>>>>>>>> protected Requirements doc;
>>>>>>>>>>> ...
>>>>>>>>>>> }
>>>>>>>>>>>
>>>>>>>>>>> In the above example, a new Employee instance will be created
>>>>>>>>>>> and
>>>>>>>>>>> the
>>>>>>>>>>> values of the id and name attributes copied. The projects and
>>>>>>>>>>> phoneNumbers collections are recreated and populated in the
>>>>>>>>>>> copy.
>>>>>>>>>>> For
>>>>>>>>>>> the entities within the new projects collection, the id
>>>>>>>>>>> attributes are
>>>>>>>>>>> copied and new Requirements objects created. Only the id
>>>>>>>>>>> attribute of
>>>>>>>>>>> the Requirement entity is copied. For the entities within the
>>>>>>>>>>> new
>>>>>>>>>>> phoneNumbers collection, only the number attribute is copied.
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>
>>>>>>
>>>>
>>>