You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cayenne.apache.org by aa...@apache.org on 2006/11/23 02:29:16 UTC

svn commit: r478423 - in /incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src: main/java/org/apache/cayenne/access/ChildDiffLoader.java test/java/org/apache/cayenne/access/NestedDataContextWriteTst.java

Author: aadamchik
Date: Wed Nov 22 17:29:15 2006
New Revision: 478423

URL: http://svn.apache.org/viewvc?view=rev&rev=478423
Log:
CAY-709: Leak-free ObjectContext
(fixing logic for nested DataContexts - Cayenne must be able to refetch objects that were deallocated from the parent context)

Modified:
    incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/access/ChildDiffLoader.java
    incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/test/java/org/apache/cayenne/access/NestedDataContextWriteTst.java

Modified: incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/access/ChildDiffLoader.java
URL: http://svn.apache.org/viewvc/incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/access/ChildDiffLoader.java?view=diff&rev=478423&r1=478422&r2=478423
==============================================================================
--- incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/access/ChildDiffLoader.java (original)
+++ incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/main/java/org/apache/cayenne/access/ChildDiffLoader.java Wed Nov 22 17:29:15 2006
@@ -19,14 +19,18 @@
 
 package org.apache.cayenne.access;
 
+import java.util.List;
+
 import org.apache.cayenne.CayenneRuntimeException;
 import org.apache.cayenne.DataObject;
+import org.apache.cayenne.ObjectContext;
 import org.apache.cayenne.ObjectId;
-import org.apache.cayenne.Persistent;
+import org.apache.cayenne.QueryResponse;
 import org.apache.cayenne.graph.GraphChangeHandler;
-import org.apache.cayenne.graph.GraphManager;
 import org.apache.cayenne.map.ObjEntity;
 import org.apache.cayenne.map.Relationship;
+import org.apache.cayenne.query.ObjectIdQuery;
+import org.apache.cayenne.query.Query;
 
 /**
  * A GraphChangeHandler that loads child ObjectContext diffs into a parent DataContext.
@@ -37,12 +41,10 @@
  */
 class ChildDiffLoader implements GraphChangeHandler {
 
-    DataContext context;
-    GraphManager graphManager;
+    ObjectContext context;
 
     ChildDiffLoader(DataContext context) {
         this.context = context;
-        this.graphManager = context.getGraphManager();
     }
 
     public void nodeIdChanged(Object nodeId, Object newId) {
@@ -75,8 +77,7 @@
     }
 
     public void nodeRemoved(Object nodeId) {
-        Persistent object = findObject(nodeId);
-        context.deleteObject(object);
+        context.deleteObject(findObject(nodeId));
     }
 
     public void nodePropertyChanged(
@@ -131,6 +132,28 @@
     }
 
     DataObject findObject(Object nodeId) {
-        return (DataObject) graphManager.getNode(nodeId);
+        // first do a lookup in ObjectStore; if even a hollow object is found, return it;
+        // if not - fetch.
+
+        DataObject object = (DataObject) context.getGraphManager().getNode(nodeId);
+        if (object != null) {
+            return object;
+        }
+
+        // skip context cache lookup, go directly to its channel
+        Query query = new ObjectIdQuery((ObjectId) nodeId);
+        QueryResponse response = context.getChannel().onQuery(context, query);
+        List objects = response.firstList();
+
+        if (objects.size() == 0) {
+            throw new CayenneRuntimeException("No object for ID exists: " + nodeId);
+        }
+        else if (objects.size() > 1) {
+            throw new CayenneRuntimeException(
+                    "Expected zero or one object, instead query matched: "
+                            + objects.size());
+        }
+
+        return (DataObject) objects.get(0);
     }
 }

Modified: incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/test/java/org/apache/cayenne/access/NestedDataContextWriteTst.java
URL: http://svn.apache.org/viewvc/incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/test/java/org/apache/cayenne/access/NestedDataContextWriteTst.java?view=diff&rev=478423&r1=478422&r2=478423
==============================================================================
--- incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/test/java/org/apache/cayenne/access/NestedDataContextWriteTst.java (original)
+++ incubator/cayenne/main/trunk/core/cayenne-jdk1.4/src/test/java/org/apache/cayenne/access/NestedDataContextWriteTst.java Wed Nov 22 17:29:15 2006
@@ -20,6 +20,7 @@
 package org.apache.cayenne.access;
 
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.List;
 
 import org.apache.art.ArtGroup;
@@ -33,6 +34,16 @@
 
 public class NestedDataContextWriteTst extends CayenneTestCase {
 
+    /**
+     * Overrides super implementation to ensure that created DataContext's ObjectStore
+     * retains unreferenced registered objects.
+     */
+    protected DataContext createDataContext() {
+        DataContext context = super.createDataContext();
+        context.getObjectStore().objectMap = new HashMap();
+        return context;
+    }
+
     public void testCommitChangesToParent() throws Exception {
         deleteTestData();
         createTestData("testFlushChanges");
@@ -317,7 +328,8 @@
             assertEquals(PersistenceState.NEW, parentMaster.getPersistenceState());
 
             PaintingInfo parentDetail1 = (PaintingInfo) context
-                    .getGraphManager().getNode(childDetail1.getObjectId());
+                    .getGraphManager()
+                    .getNode(childDetail1.getObjectId());
 
             assertNotNull(parentDetail1);
             assertEquals(PersistenceState.NEW, parentDetail1.getPersistenceState());