users@jpa-spec.java.net

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

From: Gordon Yorke <gordon.yorke_at_oracle.com>
Date: Tue, 18 Dec 2012 17:02:28 -0400

There is no requirement for a user to use copy(), the specification
already has support for partial loading of entities and providers are
currently required to support serialization so there are no barriers for
a user to serialize a tree of entities and only the loaded data would be
expected to be serialized. The only purpose of copy() is to allow users
to create a copy of a portion of an entity graph. Many users have asked
for this functionality and with EntityGraphs we now have a means to
template the operation so why not add the functionality. I see no need
for "guards" as users are intentionally creating a truncated entity
graph with a template that they have provided. Also, "guards" add
unnecessary complexity and require some sort of enhancement of the
entity classes that has not yet and should not be required by the
specification.

With respect to merge(EntityGraph) the specification is introducing
partial merges which introduce the prospect of users creating partially
populated entities and merging them without or without
copy(EntityGraph). This merge() feature is introducing more versatile
functionality and it is unfortunate that versatility can increase
complexity but that is the usual cost.

--Gordon

On 17/12/2012 1:09 PM, Emmanuel Bernard wrote:
> OK I get it now.
>
> To be honest I am quite uncomfortable with such a feature. Does everyone
> really think that this feature is a must have?
>
> I imagine that the use case you have in mind is to pass this copied
> object graph to another serialization or traversal framework that would
> otherwise traverse the JPA guards like there is no tomorrow.
>
> Our experience with Bean Validation has shown that handling guards is
> extremely easy and that the necessary contract to make a traversal /
> serialization framework aware of these is quite simple
> https://github.com/beanvalidation/beanvalidation-api/blob/master/src/main/java/javax/validation/TraversableResolver.java
>
> The solution proposed here (the copy) forces to copy an object graph
> which leads to memory duplication just to get the data serialized in
> another form. Plus the user *must* use the same graph definition for
> both `copy` and `merge` or else data loss are going to happen. I find
> the programming model quite error prone and dangerous.
>
> Emmanuel
>
> On Mon 2012-12-17 9:40, Gordon Yorke wrote:
>> Hello Emmanuel,
>> The goal of a copy graph is to produce a simple subgraph copy of
>> the entity graph for environments where enhancement/proxies may not
>> be available or where these "guards" can not be retained when then
>> graph is serialized. The developer has a template in the form of
>> the entity graph which provides the details of which attributes have
>> legitimate values and which ones should be ignored and this template
>> is highly recommended for the merge. There is no requirement for
>> "guards" embedded within the copies. In client/server environments
>> where "guards" would be available there is no need for copy() at all
>> as the same functionality is achieved serializing entities loaded
>> with a fetch graph.
>>
>> --Gordon
>> On 17/12/2012 5:25 AM, Emmanuel Bernard wrote:
>>>>> ## Use cases
>>>>>
>>>>> I would really like to get use cases associated to each of the new
>>>>> features proposed here.
>>>>>
>>>>> In particular:
>>>>> - it's unclear to me why you really need loadgraph and fetchgraph.
>>>>> - why is merge( fetchgraph ) required when you can achieve the same with
>>>>> - find( fetchgraph )
>>>>> - detach / serialize or whatever
>>>>> - merge() regular method
>>>> merge(EntityGraph) applies when the user is using copy(EntityGraph)
>>>> to detach an entity tree for serialization. If an attribute is not
>>>> present in the copy then it must not be merged. So, your example
>>>> becomes:
>>>> - find (EntityGraph eg1)
>>>> - copy(EntityGraph eg1)
>>>> - serialize out/in
>>>> - merge(EntityGraph eg1)
>>> Sure but the graph returned by copy does contain guards on uninitialized
>>> properties and associations right? Ie when a non copied property /
>>> association is traversed, some exception is raised.
>>>
>>> If that's not the case then what are you returning? null or the
>>> primitive default values? I would be strongly against that.
>>>
>>> So assuming the engine has those guards on uninitialized properties and
>>> associations, then the merge with an EntityGraph is not necessary as
>>> this information can be discovered (like we do for a regular merge).
>>>
>>> Emmanuel