openjpa-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Pinaki Poddar" <ppod...@bea.com>
Subject RE: FetchGroup and FetchAttribute question
Date Fri, 07 Sep 2007 23:07:50 GMT
Hello Teresa,

> The test result showed #2, #3, #5 and #6 were incorrect.

I could reproduce these errors.

After some analysis following are my observations:
A) The use case where fetch group A includes fetch group B was not
handled properly  
B) The recursion depth calculation for a field f which belongs to
multiple fetch
Groups but not all of them are active in a given configuration -- has a
bug
C) The LoadFetchGroup related failure is still under investigation.

As of revision 573750 (A) and (B) have been corrected against your
tests. 
  


Pinaki Poddar
972.834.2865
 

>-----Original Message-----
>From: Teresa Kan [mailto:tckan1@gmail.com] 
>Sent: Wednesday, September 05, 2007 2:15 PM
>To: dev@openjpa.apache.org
>Subject: Re: FetchGroup and FetchAttribute question
>
>Pinaki,
>Our test team wanted to test the  interaction between the 
>annotation of fetch group and the declaration of the fetch 
>type on the attributes as well as the fetch group arcitechure. 
>Yes, they may not be the real examples in a business 
>enviornment. However, they served a good understanding of 
>fetch group architecture if the test results are correct. 
> 
>After reviewed your comments,  I modified my test case to fit 
>into the openjpa test suite. In addition, I also took your 
>suggestion to move the em.findEmployee to a separate method to 
>avoid some side effort. However, the test result did not match 
>with my interpretation of the FetchGroup architecture. I like 
>to verify the following interpretation first before debugging 
>the problem. 
> 
>1) Use the annotation to define the custom fetchGroup on an 
>entity will not be automatically active during the runtime. 
>You can activate the FetchGroup thru the addFetchGroup API in 
>the application.
>2) @LoadFetchGroup does not relate to the FetchGroup. If field 
>a has @LoadFetchGroup X, when field a is loaded, it also loads 
>all fields included in fetchGroup X.
>3) If there is a fetch group defined in the persistence.xml 
>file, this will be the default fetch group along with the 
>original "default" fetch group. Therefore, the global 
>configuration will have the original default fetch group + any 
>fetch groups that are defined in the persistence.xml file. 
>.All the attributes are defined in these default fetch groups 
>will be eagerly loaded at runtime.
>4) resetFetchGroup will reset the current active FetchGroup to 
>global configuration that is specified in #3.
>5) Nesting fetch group  ( need confirmation here): when a 
>fetch group X is added to a fetch plan during the runtime, its 
>nested fetch groups should also be activated in runtime.
>6) When a fetch group X is added to a fetch plan during the 
>runtime, only this fetch group X and its nested fetch groups 
>are activated (see #5). Other fetch groups will not be 
>activiated even though those fetch groups have the same 
>attribute members as the fetch group X. 
>
>Please verify the above interpretation. The test result showed 
>#2, #3, #5 and #6 were incorrect.
>I also attached the testcases here: one without the property 
>and one with the property. You can add the following line in 
>the persistence.xml file and test with TestFetchGroupWithProperty:
><property name="openjpa.FetchGroups" 
>value="default,AggregateEmployeeFetchGroup3" /> 
>
>Thanks,
>Teresa
> 
>On 9/4/07, Pinaki Poddar <ppoddar@bea.com> wrote: 
>
>	Teresa,
>	
>	Few notes:
>	1. The entity classes had annotated certain fields 
>Fetch.LAZY and test
>	code is verifying which fields are fetched under 
>different fetch 
>	configuration. Annotating a field x which otherwise 
>would be in default
>	fetch group (say String FGEmployee.rating in your example) with
>	Fecth.LAZY will keep field x out of default fetch group.
>	So if only default fetch group is active (for example, after a 
>	resetFetchGroups() call), then 
>em.find(FGEmployee.class, id) will fetch
>	a Employee but not 'rating' field. Employee.rating will 
>only be fetched
>	if user code calls emp.getRating().
>	
>	2. But if the test code does something as follows 
>within an active 
>	transaction:
>	  boolean isRatingFetched = (emp.getRating()!=null);
>	
>	  then a Schrodinger's principle becomes active i.e. due to the
>	observation process itself, the observed gets 
>perturbed. The result of 
>	emp.getAddress() will *now* fetch the LAZY 'rating' field and
>	isRatingFetched will become true. However, 
>em.find(FGEmployee.class, id)
>	may not have fetched 'rating' which is actually what 
>the test is trying 
>	to verify.
>	Some of the attached test code is impacted by this effect.
>	The safe way to eliminate such side-effect is to commit 
>the transaction
>	and close (not clear) the entity manager *before* 
>starting to check 
>	which fields are fetched as a result of a find() or 
>query result.
>	
>	3. I would suggest that capture the oft-repeated code 
>patterns in the
>	Test case of finding an Employee under different fetch 
>configuration to 
>	put in a single method like (this one ensures that the 
>returned Employee
>	will not further fetch its state as a side-effect of 
>get() calls):
>	
>	   private FGEmployee findEmployee(Object id, boolean reset,
>	String...fetchGroups) { 
>	       EntityManager em = emf.createEntityManager();
>	
>	     OpenJPAEntityManager oem = OpenJPAPersistence.cast(em);
>	       oem.getTransaction().begin();
>	       if (reset) {
>	               oem.getFetchPlan ().resetFetchGroups();
>	               assertEquals(1,
>	oem.getFetchPlan().getFetchGroups().size());
>	               assertEquals("[default]",
>	
>Arrays.toString(oem.getFetchPlan().getFetchGroups().toArray())); 
>	       }
>	       if (fetchGroups!=null)
>	               for (String fg:fetchGroups)
>	                       oem.getFetchPlan().addFetchGroup(fg);
>	       FGEmployee emp = oem.find(FGEmployee.class, id);
>	       oem.getTransaction().commit();
>	       oem.close();
>	       return emp;
>	   }
>	
>	4. I would also suggest to use
>	TestCase.assertNull(emp.getRating()) or 
>assertNotNull(emp.getRating())
>	wherever System.out.pritln ("....") is used to verify manually.
>	Because without any asserts, Junit Tests think they pass!
>	
>	5. Another suggestion will be *not* to mix compile-time 
>FetchType.LAZY
>	and run-time fetch plans in the tests at least for initial 
>	verifications.
>	So keeping the fields without ant FecthType annotations 
>and control what
>	is fetched only by run-time manipulation of fetch plans 
>will expose the
>	functioning (and any possible bug) associated with 
>fetch groups. 
>	In a later phase, the tests can explore how mixing compile-time
>	FetchType.LAZY and run-time fetch plans change the behavior.
>	
>	
>	
>	
>	Pinaki Poddar
>	972.834.2865
>	
>	
>	>-----Original Message----- 
>	>From: Teresa Kan [mailto:tckan1@gmail.com]
>	>Sent: Tuesday, September 04, 2007 9:26 AM
>	>To: dev@openjpa.apache.org
>	>Subject: Re: FetchGroup and FetchAttribute question 
>	>
>	>Pinaki,
>	>I used the debugger to check that the FetchGroup was added
>	>when the application explicitly added that FetchGroup.
>	>I attached the testcase in this note. Please noted that I did
>	>not use the Assert to verify the result because I'm not sure
>	>about the outcome. I used the println to print out the 
>result instead.
>	>
>	>Thanks,
>	>Teresa
>	>
>	>
>	>On 8/31/07, Pinaki Poddar < ppoddar@bea.com> wrote:
>	>
>	>       Hi,
>	>       Few comments in-line....
>	>
>	>       What is the mechanics to cofirm if a field is loaded as
>	>a result of a 
>	>       API call?
>	>
>	>       Can you post a test case for us to investigate further?
>	>
>	>
>	>       Pinaki Poddar
>	>       972.834.2865
>	>
>	>
>	>       >-----Original Message----- 
>	>       >From: Teresa Kan [mailto: tckan1@gmail.com
>	><mailto:tckan1@gmail.com> ]
>	>       >Sent: Friday, August 31, 2007 11:46 AM 
>	>       >To: dev
>	>       >Subject: Re: FetchGroup and FetchAttribute question
>	>       >
>	>       >In addition to previous question, I have 
>question about the
>	>       >lifecycle of a FetchGroup and need some 
>clarifications on the 
>	>       >expected behavior. Please verify each step result is  a
>	>       >correct behavior. If they are correct, then we need to
>	>       >document those behavior in the javadoc and 
>openjpa manual: 
>	>       >
>	>       >Use the following example,
>	>       >
>	>       >@FetchGroups({
>	>       >   @FetchGroup(name="AddressFetchGroup", attributes=
>	>       >{@FetchAttribute(name="address")} ), 
>	>       >   @FetchGroup(name="RatingFetchGroup", attributes=
>	>       >{@FetchAttribute(name="rating")}),
>	>       >@FetchGroup(name="ManagerFetchGroup1A", attributes= 
>	>       >{@FetchAttribute(name= "manager" , recursionDepth=1)} )
>	>       >})
>	>       >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;
>	>       >
>	>       >..
>	>       >} 
>	>       >
>	>       >Test case:
>	>       >1.         oem.persist(employee);
>	>       >==> What happen to 3 fetchGroups? Are they 
>active at this time?
>	>       >From the debugger, the fetchGroup was set to 
>"default". At 
>	>       >this time, I can't tell whether the default 
>means those 3
>	>       >fetchGroups or the default w/o any custom 
>FetchGroups? If I
>	>       >did not reset the FetchGroup and  did not 
>explicitly add the 
>	>       >fetchGroups, both address and rating are 
>eagerly loaded.
>	>       >So it implies that all 3 fetchGroup are active when the
>	>       >employee is persisted.
>	>
>	>       The custome fetch groups are not active under this 
>	>configuration.
>	>       How are you confirming that "both address and rating
>	>are eagerly loaded"
>	>       -- looking at the SQL issued, by reflectively looking
>	>into the instance?
>	>       FetchGroups are not relevant during persist() operation.
>	>       In a clean cache, undet the 'default' configuration,
>	>for a find() or
>	>       query, rating will be fetched and address will not. 
>	>
>	>
>	>       >==> What happen if there is no LoadFetchGroup 
>annotated on
>	>       >rating? Will the AddressFetchGroup be active ?
>	>       >From the test result, this is true.. Then why 
>we need to use 
>	>       >LoadFetchGroup explicitly?
>	>
>	>       If field a has a LoadFetchGropu X -- it means "if field
>	>a is loaded also
>	>       load all fields included in fecthgroup X".
>	>LoadFetchGroup does not 
>	>       control which fetch group is active.
>	>
>	>
>	>       >
>	>       >2.          oem.getFetchPlan().resetFetchGroups();
>	>       >              oem.clean();
>	>       >==> What is the expected behavior in 
>resetFetchGroups()? 
>	>       >According to the
>	>       >javadoc:
>	>       >Resets the set of fetch groups to the list in the
>	>global configuration.
>	>       >What does the "global configuration" mean? The 
>default fetch 
>	>       >group w/o custom fetch group? or the one that 
>defined thru
>	>       >annotation? or the one in the persistence.xml file?
>	>       >
>	>
>	>       'global configuration' implies the fetch groups 
>specified in 
>	>       persistence.xml via 'openjpa.FetchGroups' property.
>	>
>	>       >I assume that 3 fetchGroups are not active. 
>>From the debugger,
>	>       >it showed the "default" which I guessed the 
>default w/o custom 
>	>       >fetch groups..
>	>       >How about the LoadFetchGroup? it seems to me 
>that this fetch
>	>       >group was deactive too. Is this an expected behavior?
>	>       >From the test result, both address and rating are NOT 
>	>eargly loaded.
>	>       >
>	>
>	>       LoadFetchGroup does not control which fetch 
>group is active.
>	>
>	>       >
>	>       >3.
>	>oem.getFetchPlan().addFetchGroups("RatingFetchGroup"); 
>	>       >==>  What is the expected behavior? The 
>RatingFetchGroup is
>	>       >added to the fetchPlan. From the debugger, I 
>saw both default
>	>       >and RatingFetchGroup.
>	>       >The test result showed the rating was eagerly 
>loaded but not 
>	>       >the address. It seems to me that the 
>resetFetchGroup() disable
>	>       >the AddressFetchGroup even though it was 
>specified in the
>	>       >rating thru LoadFetchGroup.  Is this an 
>expected behavior? 
>	>       >
>	>       >
>	>       >
>	>       >4.            FGEmployee emp = 
>oem.find(FGEmployee.class, 1);
>	>       >==> What happen to the Address and Rating fields?
>	>       >  a) if Rating does not have the 
>LoadFetchGroup annotation, 
>	>       >and no resetFetchGroup call:
>	>       >  ===> both Address and Rating are eagerly loaded.
>	>       > b) if Rating has the LoadFetchGroup annotation and no
>	>       >resetFetchGroup call: 
>	>       > ===> same as a)
>	>       > c) Regardless of  the LoadFetchGroup, if 
>resetFetchGroup is
>	>       >called and  no addFetchGroup is called:
>	>       > ==> both Address and Rating are not eagerly loaded. 
>	>       > d) If resetFetchGroup is called and addFetchGroup on
>	>       >RatingFetchGroup is
>	>       >called:
>	>       > ==> Address is LAZY and rating is eager.
>	>       > e) if resetFetchGropu is called and 
>addFetchGroup on both 
>	>       >Address and Rating fetch groups:
>	>       > ==> both Address and Rating are eagerly loaded.
>	>       >
>	>       >5) one more question, if I defined a 
>FetchGroup within a
>	>       >FetchGroup, for example, @FetchGroups({ 
>	>       >@FetchGroup(name="AggregateEmployeeFetchGroup1",
>	>       >                attributes= {
>	>       >                    @FetchAttribute(name="dept"),
>	>       >                    @FetchAttribute(name="address"), 
>	>       >                    @FetchAttribute(name="manager",
>	>recursionDepth=1)
>	>       >                } ),
>	>       > @FetchGroup(name="AggregateEmployeeFetchGroup2", 
>	>       >fetchGroups={"AggregateEmployeeFetchGroup1"} 
>), } ===> if I
>	>       >reset the fetch group, and only add the
>	>       >AggregateEmployeeFetchGroup2. Nothing will 
>happen because the 
>	>       >AggregateEmployeeFetchGroup1 is deactivated by
>	>       >resetFetchGroup(). Unless I add both 
>fetchGroup in runtime,
>	>       >none of the dept, address, manager are eagerly 
>loaded. Is this 
>	>       >an expected behavior?
>	>       >
>	>       >Please verify the above behaviors.. I can't 
>tell the lifecycle
>	>       >of the FetchGroup that associated with 
>LoadFetchGroup and
>	>       >resetFetchGroup..
>	>       >
>	>       >Thanks,
>	>       >Teresa
>	>       >
>	>       >
>	>       >
>	>       >
>	>       >
>	>       >
>	>       > 
>	>       >On 8/30/07, Teresa Kan <tckan1@gmail.com> wrote:
>	>       >>
>	>       >> If I have a fetchAttribute manager which is included
>	>in multiple 
>	>       >> FetchGroups. For example,
>	>       >>
>	>       >> @FetchGroup(name="ManagerFetchGroup1A",
>	>       >>
>	>       >> attributes= {
>	>       >> @FetchAttribute(name="manager" , 
>recursionDepth=1)} ), 
>	>       >>
>	>       >> @FetchGroup(name="ManagerFetchGroup1B",
>	>       >>
>	>       >> attributes= {
>	>       >> @FetchAttribute(name="manager" , 
>recursionDepth=-1)} ), 
>	>       >>
>	>       >> @FetchGroup(name="ManagerFetchGroup2",
>	>       >>
>	>       >> attributes= {
>	>       >> @FetchAttribute(name="manager" , 
>recursionDepth=2)} ), 
>	>       >>
>	>       >> In my test case, I did the following:
>	>       >>
>	>       >> oem.getFetchPlan().resetFetchGroups();  ===> 
>reset to default
>	>       >>
>	>       >> oem.clear();
>	>       >>
>	>       >> oem.getFetchPlan().addFetchGroups(
>	>       >> "ManagerFetchGroup1A");
>	>       >>
>	>       >> I found out that openjpa will add all 3 
>FetchGroups back to 
>	>       >the fetch
>	>       >> plan. My guess was that the manager was 
>associated with 3
>	>       >FetchGroups.
>	>       >> The recursionDepth will be set to -1. Is 
>this an expected 
>	>       >behavior? I
>	>       >> can't find any statement from the openjpa manual.
>	>Please clarifiy!
>	>       >>
>	>       >> Thanks,
>	>       >>
>	>       >> Teresa 
>	>       >>
>	>       >>
>	>       >>
>	>       >>
>	>       >>
>	>       >>
>	>       >>
>	>       >>
>	>       >>
>	>       >> 
>	>       >>
>	>       >
>	>
>	>       Notice:  This email message, together with any
>	>attachments, may contain information  of  BEA Systems,  Inc.,
>	>its subsidiaries  and  affiliated entities,  that may be 
>	>confidential,  proprietary,  copyrighted  and/or legally
>	>privileged, and is intended solely for the use of the
>	>individual or entity named in this message. If you are not the
>	>intended recipient, and have received this message in error, 
>	>please immediately return this by email and then delete it.
>	>
>	>
>	>
>	>
>	
>	Notice:  This email message, together with any 
>attachments, may contain information  of  BEA Systems,  Inc.,  
>its subsidiaries  and  affiliated entities,  that may be 
>confidential,  proprietary,  copyrighted  and/or legally 
>privileged, and is intended solely for the use of the 
>individual or entity named in this message. If you are not the 
>intended recipient, and have received this message in error, 
>please immediately return this by email and then delete it. 
>	
>
>
>

Notice:  This email message, together with any attachments, may contain information  of  BEA
Systems,  Inc.,  its subsidiaries  and  affiliated entities,  that may be confidential,  proprietary,
 copyrighted  and/or legally privileged, and is intended solely for the use of the individual
or entity named in this message. If you are not the intended recipient, and have received
this message in error, please immediately return this by email and then delete it.

Mime
View raw message