[ 
https://issues.apache.org/jira/browse/CAY-1681?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13254543#comment-13254543
 ] 

Andrus Adamchik commented on CAY-1681:
--------------------------------------

Below are my comments on the parts of the submitted patch:

diff --git 
a/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/query/PrefetchTreeNode.java
 
b/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/query/PrefetchTreeNode.java
index c81a508..ee731c7 100644
--- 
a/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/query/PrefetchTreeNode.java
+++ 
b/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/query/PrefetchTreeNode.java
@@ -33,7 +33,7 @@ import org.apache.cayenne.util.XMLSerializable;
 
 /**
  * Defines a node in a prefetch tree.
- * 
+ *
  * @since 1.2
  */
 public class PrefetchTreeNode implements Serializable, XMLSerializable {
@@ -164,6 +164,31 @@ public class PrefetchTreeNode implements Serializable, 
XMLSerializable {
     }
 
     /**
+     * Returns a clone of subtree that includes all joint children
+     * starting from this node itself and till the first occurrence of 
non-joint node
+     *
+     * @since 3.1
+     */
+    public PrefetchTreeNode cloneJointSubtree() {
        
           // [andrus] this results in the cloned root obtaining unneeded 
semantics
        // also it results in a non-null root prefetch even if there are no 
joint children
        
+        return cloneJointSubtree(null);
+    }
+
+    private PrefetchTreeNode cloneJointSubtree(PrefetchTreeNode parent) {
+        PrefetchTreeNode cloned = new PrefetchTreeNode(parent, getName());
+        cloned.setSemantics(getSemantics());
+        cloned.setPhantom(isPhantom());


        // [andrus] AdjacentJoinsOperation is already recursive AFAIK,  so here 
we have double recursion, 
        // a simple loop over parent's child nodes would probably suffice

+
+        Collection<PrefetchTreeNode> jointChildren = new 
ArrayList<PrefetchTreeNode>();
+        traverse(new AdjacentJoinsOperation(jointChildren));
+
+        for (PrefetchTreeNode jointChild : jointChildren) {
+            cloned.addChild(jointChild.cloneJointSubtree(cloned));
+        }
+
+        return cloned;
+    }
+
+    /**
diff --git 
a/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/access/DataContextDisjointByIdPrefetchTest.java
 
b/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/access/DataContextDisjointByIdPrefetchTest.java
index d5e8ed4..8a230ef 100644
--- 
a/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/access/DataContextDisjointByIdPrefetchTest.java
+++ 
b/framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/access/DataContextDisjointByIdPrefetchTest.java
@@ -227,10 +228,14 @@ public class DataContextDisjointByIdPrefetchTest extends 
ServerCase {
             public void execute() {
                 assertFalse(result.isEmpty());
                 Bag b1 = result.get(0);
-                List<?> toMany = (List<?>) 
b1.readPropertyDirectly(Bag.BALLS_PROPERTY);
-                assertNotNull(toMany);
-                assertFalse(((ValueHolder) toMany).isFault());
-                assertEquals(6, toMany.size());
+                List<Ball> balls = (List<Ball>) 
b1.readPropertyDirectly(Bag.BALLS_PROPERTY);
+                assertNotNull(balls);
+                assertFalse(((ValueHolder) balls).isFault());
+                assertEquals(6, balls.size());
+
+                for (Ball b : balls) {
+                    assertEquals(PersistenceState.COMMITTED, 
b.getPersistenceState());
+                }

// [andrus] in addition to checking for PersistenceState, would be great to 
check the value of one of the properties, just to make sure
// that prefetched objects are completely valid.
                
> Third prefetch kind - DISJOINT_BY_ID
> ------------------------------------
>
>                 Key: CAY-1681
>                 URL: https://issues.apache.org/jira/browse/CAY-1681
>             Project: Cayenne
>          Issue Type: Task
>          Components: Core Library
>            Reporter: Andrus Adamchik
>            Assignee: Andrus Adamchik
>         Attachments: CAY-1681-v2.patch, CAY-1681-v3.patch, CAY-1681-v4.patch, 
> CAY-1681-varchar-length.patch
>
>
> (here is a mailing list thread discussing the issue: 
> http://markmail.org/message/zzyd26ucfwhnacfe )
> I keep encountering a common scenario where neither JOINT or DISJOINT 
> prefetch strategies are adequate - queries with fetch limit. It is very 
> common in the application to display X most recent entries from a table with 
> millions of rows, and then drill down to the object details. E.g. assume 2 
> entities - "Order" and "LineItem", with orders having multiple line items. We 
> want 10 most recent orders, with line items prefetched, so you'd so something 
> like this:
>  SelectQuery q = new SelectQuery(Order.class);
>  q.addPrefetch("lineItems");
>  q.setFetchLimit(10);
> "Disjoint" prefetch in this situation would fetch 10 orders and ALL LineItems 
> in DB. 
> "Joint" prefetch will fetch anywhere between 1 and 10 orders, depending on 
> how many line items the first 10 orders have, i.e. fetch limit is applied to 
> to-many join, not to the query root. And this is certainly not what we want. 
> Now Cayenne already has something that can solve the problem:
> q.setPageSize(10); // same as fetch limit
> Paginated query is the most optimal way to prefetch here. Whenever a result 
> list is accessed, Cayenne would execute 2 IN () queries - one for the Orders, 
> another one - for the LineItems. Both queries are matching on a set of Order 
> PKs and are pretty efficient, and only return the objects that we care about.
> The problem with this solution is that it is counterintuitive to the user 
> (why should I set "pageSize" to make my prefetches work) and adds one extra 
> query (the IN query resolving the root object list). Would be cool to turn it 
> into a separate type of prefetch.  Something like "disjoint by id"?

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators: 
https://issues.apache.org/jira/secure/ContactAdministrators!default.jspa
For more information on JIRA, see: http://www.atlassian.com/software/jira

        

Reply via email to