I had another use for an IdentityWeakHashMap recently.

Do you have an implementation? If not... this may be the kick in the butt I need to go make one.

-Brian

On Dec 23, 2003, at 2:35 PM, Armin Waibel wrote:

Hi Andy,

do you mean we should implement a IdentityWeakHashMap?

What about using a wrapper object for all keys and override 'equals' method to do a obj==obj comparison?

class IdentityKey
    {
        Object obj;

        public IdentityKey(Object obj)
        {
            this.obj = obj;
        }

        public boolean equals(Object obj)
        {
            if(obj instanceof IdentityKey)
            {
                return this.obj == ((IdentityKey)obj).obj;
            }
            else return false;
        }

        public int hashCode()
        {
                return System.identityHashCode(obj);
        }
    }

regards,
Armin

Andy Malakov wrote:

Workaround: Replacing WeakHashMap by IdentityWeakHashMap in AnonymousPersistentField.fkCache.
IdentityWeakHashMap (similarly to java.util.IdentityHashMap) uses reference-equality in place of object-equality when comparing weak
keys. Unfortunately WeakHashMap has most of the relevant methods as private/package-private and code has to be duplicated.
----- Original Message ----- From: "Andy Malakov" <[EMAIL PROTECTED]>
To: "OJB Users List" <[EMAIL PROTECTED]>
Sent: Monday, December 22, 2003 8:10 PM
Subject: Usage WeakHashMap in AnonymousPersistentField Re: Cache and prefetched relationships
Hello All,

I found that usage of database identity in Java produces quite interesting problem in OJB:

In my application all persistent Java objects use database identity instead of Java reference identity (i.e. Persistable.equals()
is
redefined so that two persistent objects are the same if they have the same primary key and top-level class).

In OJB, for each field declared in repository there is dedicated instance of AnonymousPersistentField that stores
object-to-field-value mapping in WeakHashMap (in fkCache attribute).


Despite usage of cache (ObjectCachePerBrokerImpl in my case) it is possible that identical DB objects will end up as different
Java
objects during retrieval of complex objects.

Now imagine what happens when two identical instances are retrieved:

1). When first instance is retrieved it stores its foreign keys in AnonymousPersistentField.fkCache under instance's identity.
(happens in RowReaderDefaultImpl.buildWithReflection())


2) When second object is retrieved and stored in fkCache, first instance is probably still cached [WeakHashMap entries are cleaned
up only during GC]. Since keys are identical WeakHashMap only updates entry value and DOES NOT update entry key.


3) If Full GC happens after that moment it will dispose fcCache entry if the FIRST reference becomes soft-referenced only.

Can you please comment on this issue?

BTW From OJB client side it looks like loaded objects randomly appear without their childen. Spooky :-)

May be the real problem is duplicate instances of the same objects?

All the Best,
Andy

p.s. An additional thing - will it be possible to add fast assertion into ReferencePrefetcher.associateBatched() that will verify
that all parent objects found their children in case of non-null FK?


CollectionPrefetcher, line 117:

+          boolean childFound = false;
           for (Iterator it2 = children.iterator(); it2.hasNext(); )
           {
               relatedObject = it2.next();
               id2 = new Identity(relatedObject, pb);
               if (id.equals(id2))
               {
                   field.set(owner, relatedObject);
+                  childFound = true;
                   break;
               }
           }

+ if ( ! childFound)
+ throw new Exception ("!!! Unresolved reference: " + id + " from " + owner);





------------------------------------ Re: Cache and prefetched relationships From: Oleg Nitz Date: Mon, 06 Oct 2003 00:16:10 -0700

Hi Carlos,

On Sunday 05 October 2003 14:37, carlos wrote:

broker.getCollectionByQuery(): Optimised prefetched relationships are only
useful if object caching is enabled.


Also, using the default cache, it appears that any related objects obtained
by an optimised SQL IN() clause may be 'garbage collected' before being
assigned to the 'owning object', causing another database lookup at
assigment. I believe I've observed this behaviour retrieving many objects
(2000+) - Is this correct?

Looking at the ReferencePrefetcher implememntation, I see that this is
possible for references (not for collections). Also I see that this problem
can be easily fixed. I'll do this.


Thanks,
Oleg


--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]





--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]



Reply via email to