Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [eclipselink-dev] Need help understanding why invalid object still 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


Back to the top