I had a problem with requesting the same object twice and getting
different copies of the object. This causes inconsistency of data, data
loss, etc. I wrote a patch. It should guarantee that when you ask for the 
same object twice, you get the same object.

It would probably be good to have some sort of garbage collector on 
cleared SoftReferences. Usually walking over the cache every 1000 requests 
is adequate.

S.

-- 
Shevek                                    http://www.anarres.org/
I am the Borg.                         http://www.gothnicity.org/


--- Peer.vm.orig        2004-05-12 13:06:56.608192160 +0100
+++ Peer.vm     2004-05-12 14:27:28.962562632 +0100
@@ -1,5 +1,8 @@
 package ${package};
 
+import java.lang.ref.Reference;
+import java.lang.ref.SoftReference;
+
 import java.math.BigDecimal;
 import java.sql.Connection;
 import java.sql.SQLException;
@@ -8,6 +11,8 @@
 import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.Map;
+import java.util.HashMap;
 
 import org.apache.torque.NoRowsException;
 import org.apache.torque.TooManyRowsException;
@@ -219,6 +224,74 @@
     #end
   #end
 
+
+
+
+
+  #if ($table.IdMethod.equals("none") || $table.PrimaryKey.size() == 0)
+        /* No caching possible without primary keys. */
+  #else
+    #set ($cacheDebug = 0)
+
+       /* Cache stuff. */
+
+       /** A map from ObjectKeys to weak object references. */
+       private static Map              objectCache = new HashMap();
+
+       private static ${table.JavaName} cacheGet(ObjectKey key) {
+               Reference       ref = (Reference)objectCache.get(key);
+               if (ref == null) {
+       #if ($cacheDebug != 0)
+                       System.out.println("${table.JavaName}.cacheGet(" + key +
+                                                       "): not in cache");
+       #end
+                       return null;
+               }
+               $table.JavaName ob = (${table.JavaName})ref.get();
+               if (ob == null) {
+       #if ($cacheDebug != 0)
+                       System.out.println("${table.JavaName}.cacheGet(" + key +
+                                                       "): cleared reference");
+       #end
+                       cacheRemove(key);
+                       return null;
+               }
+       #if ($cacheDebug != 0)
+               System.out.println("${table.JavaName}.cacheGet(" + key +
+                                               "): got object");
+       #end
+               return ob;
+       }
+
+       private static void cachePut(ObjectKey key, $table.JavaName ob) {
+       #if ($cacheDebug != 0)
+               System.out.println("${table.JavaName}.cachePut(" + key + ", " + 
ob.getId() + ")");
+       #end
+               Reference       ref = (Reference)objectCache.get(key);
+               if (ref != null)
+                       if (ref.get() == ob)
+                               return;
+               objectCache.put(key, new SoftReference(ob));
+       }
+
+       private static void cacheRemove(ObjectKey key) {
+       #if ($cacheDebug != 0)
+               System.out.println("${table.JavaName}.cacheRemove(" + key +")");
+       #end
+               objectCache.remove(key);
+       }
+
+  #end
+
+
+
+
+
+
+
+
+
+
     /**
      * Method to do inserts.
      *
@@ -336,6 +409,12 @@
         {
             $table.JavaName obj = ($table.JavaName) cls.newInstance();
             ${table.JavaName}Peer.populateObject(row, offset, obj);
+                       ObjectKey       key = obj.getPrimaryKey();
+                       $table.JavaName cached = cacheGet(key);
+                       if (cached != null)
+                               return cached;
+                       else
+                               cachePut(key, obj);
   #if ($addSaveMethod)
                 obj.setModified(false);
   #end
@@ -794,6 +873,7 @@
         doInsert(buildCriteria(obj));
   #else
         obj.setPrimaryKey(doInsert(buildCriteria(obj)));
+               cachePut(obj.getPrimaryKey(), obj);
   #end
         obj.setNew(false);
         obj.setModified(false);
@@ -817,6 +897,9 @@
      */
     public static void doDelete($table.JavaName obj) throws TorqueException
     {
+  #if (! $table.IdMethod.equals("none") && $table.PrimaryKey.size() > 0)
+               cacheRemove(obj.getPrimaryKey());
+  #end
         doDelete(buildCriteria(obj));
     }
 
@@ -837,6 +920,7 @@
         doInsert(buildCriteria(obj), con);
   #else
         obj.setPrimaryKey(doInsert(buildCriteria(obj), con));
+               cachePut(obj.getPrimaryKey(), obj);
   #end
         obj.setNew(false);
         obj.setModified(false);
@@ -872,6 +956,9 @@
     public static void doDelete($table.JavaName obj, Connection con)
         throws TorqueException
     {
+  #if (! $table.IdMethod.equals("none") && $table.PrimaryKey.size() > 0)
+               cacheRemove(obj.getPrimaryKey());
+  #end
         doDelete(buildCriteria(obj), con);
     }
 
@@ -884,6 +971,7 @@
      */
     public static void doDelete(ObjectKey pk) throws TorqueException
     {
+               cacheRemove(pk);
         $basePrefix${table.JavaName}Peer
            .doDelete(pk, (Connection) null);
     }
@@ -901,6 +989,7 @@
     public static void doDelete(ObjectKey pk, Connection con)
         throws TorqueException
     {
+               cacheRemove(pk);
         doDelete(buildCriteria(pk), con);
     }
 
@@ -1003,6 +1092,10 @@
     public static $table.JavaName ${retrieveMethod}(ObjectKey pk, Connection con)
         throws TorqueException, NoRowsException, TooManyRowsException
     {
+               $table.JavaName obj = cacheGet(pk);
+               if (obj != null)
+                       return obj;
+
         Criteria criteria = buildCriteria(pk);
         List v = doSelect(criteria, con);
         if (v.size() == 0)

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

Reply via email to