[ 
https://issues.apache.org/jira/browse/OPENJPA-370?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_12540024
 ] 

Craig Russell commented on OPENJPA-370:
---------------------------------------

Joe Grassel commented:
> So, for B and C to be loaded, the lazy-loaded field that has the load fetch 
> group annotation has to be accessed while the entity is still managed.  When 
> A is faulted in, it faults B and C in automatically, even if they are never 
> accessed while the entity is managed.

True.

> So given the entity FGEmployee (using this since the code is already 
> available as an attachment, and keeps my message shorter), which (all, some, 
> or none) of the following LoadFetchGroup scenarios are valid:

> Scenario A:
> Starting environment:  No fetch groups other then "default" are active, 
> persistence context is clear of any managed entities

> 1) Start a transaction
> 2) Find/Query FGEmployee
> 3) Read rating (this causes addressGroup to be faulted in, due to the 
> @LoadFetchGroup on rating)
> 4) Commit the transaction
> 5) Clear the persistence context (not necessary for TS-CM PCs)
> 6) Read rating, since it was read while the entity was managed in step 3, its 
> data should be available
> 7) Read addressGroup, although it was not read while the entity was managed, 
> it was faulted in when addressGroup was accessed in step 3, because of the 
> @LoadFetchGroup, so it should be available.  Other lazy loaded fields, like 
> description, dept, manager, are not available at this point since they were 
> never accessed while the entity was managed, and since default was the only 
> active fetch group, they would have observed lazy loading behavior.

True.

> Scenario B:
> Starting environment: Active Fetch Groups: "default", "RatingFetchGroup".  
> Persistence context is clear of any managed entities

> 1) Start a transaction
> 2) Find/Query FGEmployee
> 3) Commit the Transaction
> 4) Clear the persistence context

> (Note, the first four steps can be condensed to just 1 for a TS-CM PS if 
> performed outside of a transaction)

> 5) Read rating, since it was targeted by the RatingFetchGroup, it should be 
> available even though it was never accessed while the entity was managed.  
> This has been tested and proven that this is the observed behavior for 
> persistable attributes identified by fetch groups.

True.

> 6) Read addressGroup.  This is the rub.  Is it available?  ratings was loaded 
> in because it was part of an active fetch plan.  I would expect that since 
> rating was loaded, and since rating has declared that addressGroup should 
> also be loaded via its @LoadFetchGroup annotation, then addressGroup should 
> be available as well.

No. Rating was not accessed when not loaded, so its load fetch group is not 
used. 

The behavior that you said you would expect does not need any additional 
concept. It can be accomplished just by defining your fetch groups. The reason 
we added load fetch groups was to handle the case where the application took a 
small probability path and accessed a field that is normally not needed. 
Because the field was now accessed, we need to go to the datastore. And without 
load fetch group, we would not be able to describe the fields needed by the 
small probability path, and would end up faulting several fields individually. 
With load fetch group, we can optimally fault in all the related fields.

> Other lazy loaded fields, like description, dept, manager, are not available 
> at this point since they were never accessed while the entity was managed, 
> and were never a member of any of the active fetch groups, they would have 
> observed lazy loading behavior.

True.

> The documentation as it is written makes it sound like both scenarios are 
> valid -- any situation where rating's data is available, addressGroup's data 
> is also supposed to be available, thanks to the @LoadFetchGroup.  Which 
> scenarios are valid interpretations of the function?  Scenario A, Scenario B, 
> both, or neither?

A, not B. 

>>Yes, this does affect the fields that are detached. If fields B and C are 
>>loaded, then they are also loaded in the detached instance. But I'd be 
>>careful calling this behavior eager loading. Eager loading is done for fields 
>>based on the fetch plan in effect for a find or query that first loads the 
>>instance into memory. The load fetch group isn't considered here. The load 
>>fetch group is only activated when you access a field that wasn't eagerly 
>>loaded.

>So, this means that Scenario A is the only scenario where @LoadFetchGroup will 
>work?  Since rating, in Scenario B, would not be considered a lazy loaded 
>field because it is a member of an active fetch plan?

True. Rating, in scenario B, is not lazy loaded. It's eagerly loaded. 

>> A slightly different slant on this is that if field A is in some fetch group 
>> FG1, and use of field A requires fields B and C, then any fetch group that 
>> includes A (e.g. FG1) should also include B and C. There's no need for a 
>> load fetch group here.

> So, in the situation where we want both B and C to be loaded if A is loaded, 
> we would either:

> 1) Do Scenario A
> 2) Have fetch groups that include A, B, and C active when the find/query is 
> performed.

True.

> If that is the case, then I think the documentation really needs to be 
> updated to make that crystal clear.  

I agree some examples would be useful here. Volunteers?

To update the description, we could change "When you access a lazy loaded field 
for the first time" to "When you access a lazy loaded field by the application 
for the first time after being queried or found".

> Otherwise, it will be easy to assume (as I did) that @LoadFetchGroups will 
> always be triggered if the persistable attribute annotated with it is loaded, 
> be it approached in Scenario A or B.  By saying "you can tell OpenJPA to load 
> all of these fields together when A is first accessed." that sounds like B 
> and C will always be loaded along with A, no matter what the loading 
> circumstance (A loaded by a getter method while the entity is managed, or A 
> loaded in by fetch group).

So you understood "When you access a lazy loaded field for the first time" that 
"access" is a find or query? We meant to intend "access" to mean "access by the 
application".

>>>This includes both non-relational and relational lazy-loaded fields.

>>I don't understand this comment. Are you referring to relationship fields?

>Yes, making sure that both attributes that make sense to be lazy loaded 
>(Strings, blobs, etc.) and relationships (any, although the collection based 
>relationships are lazy by default) are included under consideration here.

Yes, the same rules apply to relationship fields. If they are lazy loaded, not 
part of any active fetch group, and then accessed by the application; when they 
are fetched from the datastore, the current fetch plan is augmented with the 
load fetch group of the relationship field and the fields that are in the 
augmented fetch plan are loaded from the datastore. This might load additional 
fields in the instance containing the lazy loaded relationship field, as well 
as loading the related object(s) according to the augmented fetch plan.

> LoadFetchGroup annotation was not recognized during the fetch1
> --------------------------------------------------------------
>
>                 Key: OPENJPA-370
>                 URL: https://issues.apache.org/jira/browse/OPENJPA-370
>             Project: OpenJPA
>          Issue Type: Bug
>          Components: kernel
>    Affects Versions: 1.0.1, 1.0.2, 1.1.0
>            Reporter: Teresa Kan
>            Assignee: Teresa Kan
>             Fix For: 1.0.2, 1.1.0
>
>         Attachments: OPENJPA_370_2.patch, smime.p7s, TestFetchGroup.zip, 
> TestJIRA370.zip
>
>
> Employee class has a LoadFetchGroup annotation defined on the Rating field, 
> when getRating was called, the address should be returned also. However, 
> openjpa did not handle the LoadFetchGroup correctly, therefore, address was 
> not eargly fetched.
> public class FGEmployee{
>     @Id
>     private int id;
>  
>     @OneToOne(fetch=FetchType.LAZY) 
>     private FGAddress address;
>  
>     @Basic(fetch=FetchType.LAZY)
>     @LoadFetchGroup("AddressFetchGroup")
>     private String rating;
>  
>     @ManyToOne(fetch=FetchType.LAZY)
>     private FGManager manager;
> ..
> }

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.

Reply via email to