code: protected void putToFieldCache(Object key, Object value)
      {
          if (key != null)
          {
              if (fkCache == null)
              {
                  fkCache = new ReferenceIdentityMap (ReferenceIdentityMap.WEAK, ReferenceIdentityMap.HARD, true);
              }
              if (value != null)
                   fkCache.put(key, value);
               else
                   fkCache.remove (key);
          }
      }
docs: /*
  Use ReferenceIdentityMap (with weak key and hard value setting) instead of
  WeakHashMap to hold anonymous field values. Here is an snip of the mail from Andy Malakov:
  <snip>
  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.
  </snip>