You are viewing a plain text version of this content. The canonical link for it is here.
Posted to ojb-dev@db.apache.org by ar...@apache.org on 2004/01/24 20:09:24 UTC

cvs commit: db-ojb/src/java/org/apache/ojb/broker/metadata/fieldaccess AnonymousPersistentField.java

arminw      2004/01/24 11:09:24

  Modified:    src/java/org/apache/ojb/broker/metadata/fieldaccess
                        AnonymousPersistentField.java
  Log:
  remove workaround for object identity problem, because it doesn't really work :-(
  We need a WeakIdentityHashMap to solve the problem.
  
  Revision  Changes    Path
  1.9       +30 -61    db-ojb/src/java/org/apache/ojb/broker/metadata/fieldaccess/AnonymousPersistentField.java
  
  Index: AnonymousPersistentField.java
  ===================================================================
  RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/broker/metadata/fieldaccess/AnonymousPersistentField.java,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- AnonymousPersistentField.java	7 Jan 2004 19:11:10 -0000	1.8
  +++ AnonymousPersistentField.java	24 Jan 2004 19:09:24 -0000	1.9
  @@ -87,18 +87,45 @@
           return getFromFieldCache(anObject);
       }
   
  +/*
  +    TODO: Use WeakIdentityHashMap instead WeakHashMap to hold anonymous field values
  +
  +    Here is an snip of the mail from Andy Malakov:
  +
  +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.
  +    */
       protected void  putToFieldCache(Object key, Object value)
       {
           if(fkCache == null)
           {
               fkCache = new WeakHashMap();
           }
  -        fkCache.put(new IdentityKey(key), value);
  +        fkCache.put(key, value);
       }
   
       protected Object getFromFieldCache(Object key)
       {
  -        return fkCache != null ? fkCache.get(new IdentityKey(key)) : null;
  +        return fkCache != null ? fkCache.get(key) : null;
       }
   
       /**
  @@ -134,63 +161,5 @@
       public boolean usesAccessorsAndMutators()
       {
           return false;
  -    }
  -
  -    //******************************************************************
  -    // inner class
  -    //******************************************************************
  -    /*
  -    TODO: replace this workaround with a IdentityWeakHashMap
  -    arminw:
  -    Workaround till we can use a IdentityWeakHashMap implementation.
  -    WeakHashMap use obj.equals(...) method to compare the object key in the
  -    map. Better to use an identity comparison.
  -
  -    Here is an snip of the mail from Andy Malakov:
  -
  -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.
  -    */
  -    static class IdentityKey
  -    {
  -        Object obj_;
  -
  -        public IdentityKey(Object obj)
  -        {
  -            this.obj_ = obj;
  -        }
  -
  -        public boolean equals(Object key)
  -        {
  -            if(key instanceof IdentityKey)
  -            {
  -                return this.obj_ == ((IdentityKey)key).obj_;
  -            }
  -            else return false;
  -        }
  -
  -        public int hashCode()
  -		{
  -			return System.identityHashCode(obj_);
  -		}
       }
   }
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: ojb-dev-unsubscribe@db.apache.org
For additional commands, e-mail: ojb-dev-help@db.apache.org