It seems to be a regression; our old unit tests are failing different ways.
 
We execute a query via UOW. A child of the returned object is returned 
stale; we can see that it is stale in the cache by calling API and by 
debugging the CacheKey.
 
 From the stack you can confirm that the stale child object is retrieved 
from the session cache and not the UOW because of this -> 
getAndCloneCacheKeyFromParent
 
Where in "Traversing a direct relationship" does the refresh supposed to 
occur?
 
We rarely use indirection in our application, so this relation was 
direct relationship.
 
So far I did notice this strange behavior in the following code:
 
Extract from TopLink source code class UnitOfWorkImpl. In some scenario 
collection getNewObjectsCloneToOriginal doesn’t have the object but 
getNewObjectsOriginalToClone has it! So the expression [if (original != 
*null*)], which seems an insignificant optimization, is creating an 
issue when the assumption that both getNewObjectsCloneToOriginal() and 
getNewObjectsOriginalToClone() are always in sync is not true.
 
// Remove object from the new object cache                       
// PERF: Avoid initialization of new objects if none.
     *if* (hasNewObjects()) {
          Object original = getNewObjectsCloneToOriginal().remove(object);
            *if* (original != *null*) {
                getNewObjectsOriginalToClone().remove(original);
            }
     }
 
 
-----Original Message-----
From: eclipselink-dev-bounces@xxxxxxxxxxx 
[mailto:eclipselink-dev-bounces@xxxxxxxxxxx] On Behalf Of Tom Ware
Sent: Tuesday, May 19, 2009 11:20 AM
To: Dev mailing list for Eclipse Persistence Services
Subject: Re: [eclipselink-dev] Need help understanding why invalid 
objectstill returned without refresh when read via UOW
 
Hi Sebastien,
 
   What, specifically are you doing when you see this issue?  From the 
stack
trace, I see you are executing some kind of a query.  What kind of 
query?  Is
the behavior always the same, or does it depend on whether the object 
returned
by your query is already registered in the UnitOfWork?
 
   In general, the getFromIdentityMap code in UnitOfWork is designed to 
always
return a value whether or not the object is invalidated in other levels of
caching in order to maintain identity within the transaction the UnitOfWork
represents.
 
   In the bug you mention below, we adjusted the behavior of the 
UnitOfWork as a
whole to deal better with a list of circumstances list in the bug:
 
--
When an object is registered in a UnitOfWork through:
a) Direct query execution against the UOW
b) Session.read* calls (which execute a query)
c) Traversing a direct relationship
d) traversing an indirect relationship
--
 
   Has this behavior actually changed or have you encountered a new 
variant of
the use case.  (i.e. is it possible to write code that succeeds on 
TopLink 10.x
and fails on EclipseLink 1.1.1)
 
   From your questions: The comment should definitely be updated and 
depending
on what we determine from our discussion about this issue, it is 
possible that
we will want to update the code path you are seeing in your stack 
trace.  The
list above from the TopLink bug-fix provides a list of areas where we 
would like
to be doing the refresh for you.
 
-Tom
 
Sebastien Tardif wrote:
 The original issue was fixed in TopLink 10.x under bug/patch 6865193 -
 INVALID OBJECTS IN CACHE SHOULD BE REFRESHED WHEN REGISTERED IN UOW.
 But now I'm testing my production application using EclipseLink 1.1.1
 RC1 and the bug is back. Simple test case doesn't fail! So besides
 answering questions below, if someone wants to have a live trace session
 on my desktop using my application for test case that's a possibility.
 In the stack below getAndCloneCacheKeyFromParent is called with
 shouldReturnInvalidatedObjects ==  true while the object is invalid, so
 the code in getAndCloneCacheKeyFromParent still return the object
 because of this condition:
 if ((cacheKey != null) && (shouldReturnInvalidatedObjects ||
 !descriptor.getCacheInvalidationPolicy().isInvalidated(cacheKey))) {
 Strangely the caller passing true for shouldReturnInvalidatedObjects has
 this comment:
 //Bug#4613774  In the parent session, only return the object if it has
 not been Invalidated
        return getAndCloneCacheKeyFromParent(primaryKey, theClass,
 shouldReturnInvalidatedObjects, descriptor);
 True is hardcoded in the code of line 327:
 *public* Object getFromIdentityMap(Vector primaryKey, Class theClass,
 ClassDescriptor descriptor) {
        *return* getFromIdentityMap(primaryKey, theClass, *true*,
 descriptor);
    }
 So the questions are:
 1-    Does the following comment wrong? only return the object if it has
 not been Invalidated
 2-    Should line 327 be modified to pass false?
 3-    Where is the responsibility to refresh the invalid object?
 Daemon Thread [WebContainer : 0] (Suspended)  
     
 UnitOfWorkIdentityMapAccessor.getAndCloneCacheKeyFromParent(Vector,
 Class, boolean, ClassDescriptor) line: 136   
      UnitOfWorkIdentityMapAccessor.getFromIdentityMap(Vector, Class,
 boolean, ClassDescriptor) line: 110  
     
UnitOfWorkIdentityMapAccessor(IdentityMapAccessor).getFromIdentityMap(Vector, 
 Class, ClassDescriptor) line: 327  
       UnitOfWorkImpl.registerExistingObject(Object, ClassDescriptor)
 line: 3781   
      UnitOfWorkImpl.registerExistingObject(Object) line: 3741  
     
 OneToOneMapping(ObjectReferenceMapping).buildCloneForPartObject(Object,
 Object, Object, UnitOfWorkImpl, boolean) line: 68 
      NoIndirectionPolicy.cloneAttribute(Object, Object, Object,
 UnitOfWorkImpl, boolean) line: 72  
      OneToOneMapping(ForeignReferenceMapping).buildClone(Object,
 Object, UnitOfWorkImpl) line: 156 
      ObjectBuilder.populateAttributesForClone(Object, Object,
 UnitOfWorkImpl) line: 2627
      UnitOfWorkImpl.populateAndRegisterObject(Object, Object, CacheKey,
 CacheKey, ClassDescriptor) line: 3537 
      UnitOfWorkImpl.cloneAndRegisterObject(Object, CacheKey, CacheKey,
 ClassDescriptor) line: 923 
      UnitOfWorkImpl.cloneAndRegisterObject(Object, CacheKey,
 ClassDescriptor) line: 832
     
 UnitOfWorkIdentityMapAccessor.getAndCloneCacheKeyFromParent(Vector,
 Class, boolean, ClassDescriptor) line: 171  
      UnitOfWorkIdentityMapAccessor.getFromIdentityMap(Vector, Class,
 boolean, ClassDescriptor) line: 110  
     
UnitOfWorkIdentityMapAccessor(IdentityMapAccessor).getFromIdentityMap(Vector, 
 Class, ClassDescriptor) line: 327  
      UnitOfWorkImpl.registerExistingObject(Object, ClassDescriptor)
 line: 3781   
      UnitOfWorkImpl.registerExistingObject(Object) line: 3741  
     
 ReadObjectQuery(ObjectBuildingQuery).registerIndividualResult(Object,
 UnitOfWorkImpl, JoinedAttributeManager) line: 362 
      ObjectBuilder.buildWorkingCopyCloneNormally(ObjectBuildingQuery,
 AbstractRecord, UnitOfWorkImpl, Vector, ClassDescriptor,
 JoinedAttributeManager) line: 584  
      ObjectBuilder.buildObjectInUnitOfWork(ObjectBuildingQuery,
 JoinedAttributeManager, AbstractRecord, UnitOfWorkImpl, Vector,
 ClassDescriptor) line: 544     
      ObjectBuilder.buildObject(ObjectBuildingQuery, AbstractRecord,
 JoinedAttributeManager) line: 485 
      ObjectBuilder.buildObject(ObjectLevelReadQuery, AbstractRecord)
 line: 437   
      ReadObjectQuery(ObjectLevelReadQuery).buildObject(AbstractRecord)
 line: 569 
      ReadObjectQuery.registerResultInUnitOfWork(Object, UnitOfWorkImpl,
 AbstractRecord, boolean) line: 712    
      ReadObjectQuery.executeObjectLevelReadQuery() line: 436   
      ReadObjectQuery(ObjectLevelReadQuery).executeDatabaseQuery() line:
 928
      ReadObjectQuery(DatabaseQuery).execute(AbstractSession,
 AbstractRecord) line: 664 
      ReadObjectQuery(ObjectLevelReadQuery).execute(AbstractSession,
 AbstractRecord) line: 889 
      ReadObjectQuery.execute(AbstractSession, AbstractRecord) line:
 397    
     
 ReadObjectQuery(ObjectLevelReadQuery).executeInUnitOfWork(UnitOfWorkImpl,
 AbstractRecord) line: 952   
      UnitOfWorkImpl.internalExecuteQuery(DatabaseQuery, AbstractRecord)
 line: 2755
      UnitOfWorkImpl(AbstractSession).executeQuery(DatabaseQuery,
 AbstractRecord, int) line: 1181
 ------------------------------------------------------------------------
 _______________________________________________
 eclipselink-dev mailing list
 eclipselink-dev@xxxxxxxxxxx
 https://dev.eclipse.org/mailman/listinfo/eclipselink-dev
_______________________________________________
eclipselink-dev mailing list
eclipselink-dev@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/eclipselink-dev
------------------------------------------------------------------------
_______________________________________________
eclipselink-dev mailing list
eclipselink-dev@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/eclipselink-dev