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"/>