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 2012/04/11 10:13:35 UTC

svn commit: r1324620 - in /cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src: main/java/org/apache/cayenne/access/ test/java/org/apache/cayenne/access/ test/java/org/apache/cayenne/testdo/testmap/auto/ test/resources/

Author: aadamchik
Date: Wed Apr 11 08:13:35 2012
New Revision: 1324620

URL: http://svn.apache.org/viewvc?rev=1324620&view=rev
Log:
CAY-1681 Third prefetch kind - DISJOINT_BY_ID

CAY-1681-v3.patch by Andrei Veprev ... everything should work, but still a few untested scnearios remain
also may need to expand the unit tests to check the prefetched object state

Modified:
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/HierarchicalObjectResolver.java
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/PrefetchProcessorJointNode.java
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/PrefetchProcessorTreeBuilder.java
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/access/DataContextDisjointByIdPrefetchTest.java
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/testmap/auto/_Bag.java
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/resources/testmap.map.xml

Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/HierarchicalObjectResolver.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/HierarchicalObjectResolver.java?rev=1324620&r1=1324619&r2=1324620&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/HierarchicalObjectResolver.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/HierarchicalObjectResolver.java Wed Apr 11 08:13:35 2012
@@ -19,6 +19,7 @@
 
 package org.apache.cayenne.access;
 
+import java.util.Collection;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
@@ -162,7 +163,12 @@ class HierarchicalObjectResolver {
                 pathPrefix = buffer.append(".").toString();
             }
 
-            for (Object dataRow : parentProcessorNode.getDataRows()) {
+            List parentDataRows = parentProcessorNode.getDataRows();
+            if (parentProcessorNode instanceof PrefetchProcessorJointNode) {
+                parentDataRows = ((PrefetchProcessorJointNode) parentProcessorNode).getResolvedRows();
+            }
+
+            for (Object dataRow : parentDataRows) {
 
                 Expression allJoinsQualifier = null;
                 for (DbJoin join : lastDbRelationship.getJoins()) {
@@ -181,6 +187,10 @@ class HierarchicalObjectResolver {
                 query.orQualifier(allJoinsQualifier);
             }
 
+            // TODO: need to pass the remaining tree to make joint prefetches work
+            // but not sure is it a good idea to do it in that way
+            query.setPrefetchTree(node);
+
             query.setFetchingDataRows(true);
             if (relationship.isSourceIndependentFromTargetChange()) {
                 // setup extra result columns to be able to relate result rows to the
@@ -256,7 +266,7 @@ class HierarchicalObjectResolver {
 
             // TODO: see TODO in ObjectResolver.relatedObjectsFromDataRows
 
-            if (node.isDisjointPrefetch() && !needToSaveDuplicates) {
+            if ((node.isDisjointPrefetch() || node.isDisjointByIdPrefetch()) && !needToSaveDuplicates) {
                 PrefetchProcessorNode processorNode = (PrefetchProcessorNode) node;
                 if (processorNode.isJointChildren()) {
                     List<Persistent> objects = processorNode.getObjects();

Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/PrefetchProcessorJointNode.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/PrefetchProcessorJointNode.java?rev=1324620&r1=1324619&r2=1324620&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/PrefetchProcessorJointNode.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/PrefetchProcessorJointNode.java Wed Apr 11 08:13:35 2012
@@ -155,7 +155,8 @@ class PrefetchProcessorJointNode extends
 
         // build a DB path .. find parent node that terminates the joint group...
         PrefetchTreeNode jointRoot = this;
-        while (jointRoot.getParent() != null && !jointRoot.isDisjointPrefetch()) {
+        while (jointRoot.getParent() != null && !jointRoot.isDisjointPrefetch()
+                && !jointRoot.isDisjointByIdPrefetch()) {
             jointRoot = jointRoot.getParent();
         }
 

Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/PrefetchProcessorTreeBuilder.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/PrefetchProcessorTreeBuilder.java?rev=1324620&r1=1324619&r2=1324620&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/PrefetchProcessorTreeBuilder.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/PrefetchProcessorTreeBuilder.java Wed Apr 11 08:13:35 2012
@@ -117,7 +117,8 @@ final class PrefetchProcessorTreeBuilder
 
         // set "jointChildren" flag on all nodes in the same "join group"
         PrefetchProcessorNode groupNode = decorated;
-        while (groupNode.getParent() != null && !groupNode.isDisjointPrefetch()) {
+        while (groupNode.getParent() != null && !groupNode.isDisjointPrefetch()
+                && !groupNode.isDisjointByIdPrefetch()) {
             groupNode = (PrefetchProcessorNode) groupNode.getParent();
             groupNode.setJointChildren(true);
         }

Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/access/DataContextDisjointByIdPrefetchTest.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/access/DataContextDisjointByIdPrefetchTest.java?rev=1324620&r1=1324619&r2=1324620&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/access/DataContextDisjointByIdPrefetchTest.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/access/DataContextDisjointByIdPrefetchTest.java Wed Apr 11 08:13:35 2012
@@ -11,6 +11,7 @@ import org.apache.cayenne.testdo.testmap
 import org.apache.cayenne.testdo.testmap.Ball;
 import org.apache.cayenne.testdo.testmap.Box;
 import org.apache.cayenne.testdo.testmap.BoxInfo;
+import org.apache.cayenne.testdo.testmap.Thing;
 import org.apache.cayenne.unit.di.DataChannelInterceptor;
 import org.apache.cayenne.unit.di.UnitTestClosure;
 import org.apache.cayenne.unit.di.server.ServerCase;
@@ -149,7 +150,7 @@ public class DataContextDisjointByIdPref
                     assertEquals(PersistenceState.COMMITTED, b.getPersistenceState());
                     names.add(b.getName());
                 }
-                
+
                 assertTrue(names.contains("Y"));
                 assertTrue(names.contains("Z"));
             }
@@ -234,6 +235,27 @@ public class DataContextDisjointByIdPref
         });
     }
 
+    public void testLongFlattenedRelationship() throws Exception {
+        createBagWithTwoBoxesAndPlentyOfBallsDataSet();
+
+        SelectQuery query = new SelectQuery(Bag.class);
+        query.addPrefetch(Bag.THINGS_PROPERTY)
+                .setSemantics(PrefetchTreeNode.DISJOINT_BY_ID_PREFETCH_SEMANTICS);
+        final List<Bag> result = context.performQuery(query);
+
+        queryInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
+
+            public void execute() {
+                assertFalse(result.isEmpty());
+                Bag b1 = result.get(0);
+                List<?> toMany = (List<?>) b1.readPropertyDirectly(Bag.THINGS_PROPERTY);
+                assertNotNull(toMany);
+                assertFalse(((ValueHolder) toMany).isFault());
+                assertEquals(6, toMany.size());
+            }
+        });
+    }
+
     public void testMultiColumnRelationship() throws Exception {
         createBagWithTwoBoxesAndPlentyOfBallsDataSet();
 
@@ -269,4 +291,59 @@ public class DataContextDisjointByIdPref
             }
         });
     }
+
+    public void testJointPrefetchInParent() throws Exception {
+        createBagWithTwoBoxesAndPlentyOfBallsDataSet();
+
+        SelectQuery query = new SelectQuery(Box.class);
+        query.addPrefetch(Box.BALLS_PROPERTY).setSemantics(PrefetchTreeNode.JOINT_PREFETCH_SEMANTICS);
+        query.addPrefetch(Box.BALLS_PROPERTY + "." + Ball.THING_PROPERTY)
+                .setSemantics(PrefetchTreeNode.DISJOINT_BY_ID_PREFETCH_SEMANTICS);
+        final List<Box> result = context.performQuery(query);
+
+        queryInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
+            public void execute() {
+                assertFalse(result.isEmpty());
+                Box box = result.get(0);
+
+                List<Ball> balls = (List<Ball>) box.readPropertyDirectly(Box.BALLS_PROPERTY);
+                assertNotNull(balls);
+                assertFalse(((ValueHolder) balls).isFault());
+                assertEquals(2, balls.size());
+
+                Ball ball = balls.get(0);
+                Thing thing = (Thing) ball.readPropertyDirectly(Ball.THING_PROPERTY);
+                assertNotNull(thing);
+            }
+        });
+    }
+
+    public void testJointPrefetchInChild() throws Exception {
+        createBagWithTwoBoxesAndPlentyOfBallsDataSet();
+
+        SelectQuery query = new SelectQuery(Bag.class);
+        query.addPrefetch(Bag.BOXES_PROPERTY)
+                .setSemantics(PrefetchTreeNode.DISJOINT_BY_ID_PREFETCH_SEMANTICS);
+        query.addPrefetch(Bag.BOXES_PROPERTY + "." + Box.BALLS_PROPERTY)
+                .setSemantics(PrefetchTreeNode.JOINT_PREFETCH_SEMANTICS);
+        final List<Bag> result = context.performQuery(query);
+
+        queryInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
+            public void execute() {
+                assertFalse(result.isEmpty());
+
+                Bag bag = result.get(0);
+                List<Box> boxes = (List<Box>) bag.readPropertyDirectly(Bag.BOXES_PROPERTY);
+                assertNotNull(boxes);
+                assertFalse(((ValueHolder) boxes).isFault());
+                assertEquals(2, boxes.size());
+
+                Box box = boxes.get(0);
+                List<Ball> balls = (List<Ball>) box.readPropertyDirectly(Box.BALLS_PROPERTY);
+                assertNotNull(balls);
+                assertFalse(((ValueHolder) balls).isFault());
+                assertEquals(2, balls.size());
+            }
+        });
+    }
 }

Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/testmap/auto/_Bag.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/testmap/auto/_Bag.java?rev=1324620&r1=1324619&r2=1324620&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/testmap/auto/_Bag.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/testdo/testmap/auto/_Bag.java Wed Apr 11 08:13:35 2012
@@ -5,6 +5,7 @@ import java.util.List;
 import org.apache.cayenne.CayenneDataObject;
 import org.apache.cayenne.testdo.testmap.Ball;
 import org.apache.cayenne.testdo.testmap.Box;
+import org.apache.cayenne.testdo.testmap.Thing;
 
 /**
  * Class _Bag was generated by Cayenne.
@@ -17,31 +18,38 @@ public abstract class _Bag extends Cayen
     public static final String NAME_PROPERTY = "name";
     public static final String BALLS_PROPERTY = "balls";
     public static final String BOXES_PROPERTY = "boxes";
+    public static final String THINGS_PROPERTY = "things";
 
     public static final String ID_PK_COLUMN = "ID";
 
     public void setName(String name) {
-        writeProperty(NAME_PROPERTY, name);
+        writeProperty("name", name);
     }
     public String getName() {
-        return (String)readProperty(NAME_PROPERTY);
+        return (String)readProperty("name");
     }
 
     @SuppressWarnings("unchecked")
     public List<Ball> getBalls() {
-        return (List<Ball>)readProperty(BALLS_PROPERTY);
+        return (List<Ball>)readProperty("balls");
     }
 
 
     public void addToBoxes(Box obj) {
-        addToManyTarget(BOXES_PROPERTY, obj, true);
+        addToManyTarget("boxes", obj, true);
     }
     public void removeFromBoxes(Box obj) {
-        removeToManyTarget(BOXES_PROPERTY, obj, true);
+        removeToManyTarget("boxes", obj, true);
     }
     @SuppressWarnings("unchecked")
     public List<Box> getBoxes() {
-        return (List<Box>)readProperty(BOXES_PROPERTY);
+        return (List<Box>)readProperty("boxes");
+    }
+
+
+    @SuppressWarnings("unchecked")
+    public List<Thing> getThings() {
+        return (List<Thing>)readProperty("things");
     }
 
 

Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/resources/testmap.map.xml
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/resources/testmap.map.xml?rev=1324620&r1=1324619&r2=1324620&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/resources/testmap.map.xml (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/test/resources/testmap.map.xml Wed Apr 11 08:13:35 2012
@@ -747,6 +747,7 @@
 	<obj-relationship name="toExhibit" source="ArtistExhibit" target="Exhibit" deleteRule="Nullify" db-relationship-path="toExhibit"/>
 	<obj-relationship name="balls" source="Bag" target="Ball" deleteRule="Deny" db-relationship-path="BOXES.BALLS"/>
 	<obj-relationship name="boxes" source="Bag" target="Box" deleteRule="Deny" db-relationship-path="BOXES"/>
+	<obj-relationship name="things" source="Bag" target="Thing" deleteRule="Deny" db-relationship-path="BOXES.BOX_THING.THING"/>
 	<obj-relationship name="box" source="Ball" target="Box" deleteRule="Nullify" db-relationship-path="BOX"/>
 	<obj-relationship name="thing" source="Ball" target="Thing" deleteRule="Nullify" db-relationship-path="THING"/>
 	<obj-relationship name="binaryPKDetails" source="BinaryPKTest1" target="BinaryPKTest2" db-relationship-path="binaryPKDetails"/>