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 2010/11/10 22:32:08 UTC

svn commit: r1033722 - in /cayenne/main/trunk: docs/doc/src/main/resources/ framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/

Author: aadamchik
Date: Wed Nov 10 21:32:08 2010
New Revision: 1033722

URL: http://svn.apache.org/viewvc?rev=1033722&view=rev
Log:
CAY-1503 POST_LOAD is not called on prefetched objects

Modified:
    cayenne/main/trunk/docs/doc/src/main/resources/RELEASE-NOTES.txt
    cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DataDomainQueryAction.java
    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/ObjectResolver.java

Modified: cayenne/main/trunk/docs/doc/src/main/resources/RELEASE-NOTES.txt
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/docs/doc/src/main/resources/RELEASE-NOTES.txt?rev=1033722&r1=1033721&r2=1033722&view=diff
==============================================================================
--- cayenne/main/trunk/docs/doc/src/main/resources/RELEASE-NOTES.txt (original)
+++ cayenne/main/trunk/docs/doc/src/main/resources/RELEASE-NOTES.txt Wed Nov 10 21:32:08 2010
@@ -82,6 +82,7 @@ CAY-1488 OutOfMemory when selecting "Rem
 CAY-1489 NPE using DataContext.objectFromDataRow for a nested context
 CAY-1490 Maven cgen: all and datamap modes can not be activated
 CAY-1496 Problem in derby: comparison operators are not supported on Clob object values.
+CAY-1503 POST_LOAD is not called on prefetched objects
 CAY-1505 Callbacks: POST_UPDATE is called on updated removed object, instead of POST_REMOVE
 
 ----------------------------------

Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DataDomainQueryAction.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DataDomainQueryAction.java?rev=1033722&r1=1033721&r2=1033722&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DataDomainQueryAction.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DataDomainQueryAction.java Wed Nov 10 21:32:08 2010
@@ -561,26 +561,26 @@ class DataDomainQueryAction implements Q
 
         abstract void convert(List<T> mainRows);
 
-        protected List<Persistent> toObjects(
+        protected PrefetchProcessorNode toResultsTree(
                 ClassDescriptor descriptor,
                 PrefetchTreeNode prefetchTree,
                 List<DataRow> normalizedRows) {
-            List<Persistent> objects;
 
             // take a shortcut when no prefetches exist...
             if (prefetchTree == null) {
-                objects = new ObjectResolver(context, descriptor, metadata
+                return new ObjectResolver(context, descriptor, metadata
                         .isRefreshingObjects())
-                        .synchronizedObjectsFromDataRows(normalizedRows);
+                        .synchronizedRootResultNodeFromDataRows(normalizedRows);
             }
             else {
-                HierarchicalObjectResolver resolver = new HierarchicalObjectResolver(context, metadata);
-                objects = resolver.synchronizedObjectsFromDataRows(
+                HierarchicalObjectResolver resolver = new HierarchicalObjectResolver(
+                        context,
+                        metadata);
+                return resolver.synchronizedRootResultNodeFromDataRows(
                         prefetchTree,
                         normalizedRows,
                         prefetchResultsByPath);
             }
-            return objects;
         }
 
         protected void updateResponse(List sourceObjects, List targetObjects) {
@@ -594,6 +594,24 @@ class DataDomainQueryAction implements Q
                 throw new IllegalStateException("Unknown response object: " + response);
             }
         }
+
+        protected void performPostLoadCallbacks(
+                PrefetchProcessorNode node,
+                LifecycleCallbackRegistry callbackRegistry) {
+
+            if (node.hasChildren()) {
+                for (PrefetchTreeNode child : node.getChildren()) {
+                    performPostLoadCallbacks(
+                            (PrefetchProcessorNode) child,
+                            callbackRegistry);
+                }
+            }
+
+            List<Persistent> objects = node.getObjects();
+            if (objects != null) {
+                callbackRegistry.performCallbacks(LifecycleEvent.POST_LOAD, objects);
+            }
+        }
     }
 
     class SingleObjectConversionStrategy extends ObjectConversionStrategy<DataRow> {
@@ -604,8 +622,11 @@ class DataDomainQueryAction implements Q
             ClassDescriptor descriptor = metadata.getClassDescriptor();
             PrefetchTreeNode prefetchTree = metadata.getPrefetchTree();
 
-            List<Persistent> objects = toObjects(descriptor, prefetchTree, mainRows);
-            updateResponse(mainRows, objects);
+            PrefetchProcessorNode node = toResultsTree(descriptor, prefetchTree, mainRows);
+            List<Persistent> objects = node.getObjects();
+            updateResponse(mainRows, objects != null
+                    ? objects
+                    : new ArrayList<Persistent>(1));
 
             // apply POST_LOAD callback
             LifecycleCallbackRegistry callbackRegistry = context
@@ -613,7 +634,7 @@ class DataDomainQueryAction implements Q
                     .getCallbackRegistry();
 
             if (!callbackRegistry.isEmpty(LifecycleEvent.POST_LOAD)) {
-                callbackRegistry.performCallbacks(LifecycleEvent.POST_LOAD, objects);
+                performPostLoadCallbacks(node, callbackRegistry);
             }
         }
     }
@@ -628,7 +649,7 @@ class DataDomainQueryAction implements Q
 
     class MixedConversionStrategy extends ObjectConversionStrategy<Object[]> {
 
-        protected List<Persistent> toObjects(
+        protected PrefetchProcessorNode toResultsTree(
                 ClassDescriptor descriptor,
                 PrefetchTreeNode prefetchTree,
                 List<Object[]> rows,
@@ -639,7 +660,7 @@ class DataDomainQueryAction implements Q
             for (int i = 0; i < len; i++) {
                 rowsColumn.add((DataRow) rows.get(i)[position]);
             }
-            List<Persistent> objects;
+
             if (prefetchTree != null) {
                 PrefetchTreeNode prefetchTreeNode = null;
                 for (PrefetchTreeNode prefetch : prefetchTree.getChildren()) {
@@ -655,22 +676,23 @@ class DataDomainQueryAction implements Q
                 }
                 prefetchTree = prefetchTreeNode;
             }
+
             if (prefetchTree == null) {
-                objects = new ObjectResolver(context, descriptor, metadata
+                return new ObjectResolver(context, descriptor, metadata
                         .isRefreshingObjects())
-                        .synchronizedObjectsFromDataRows(rowsColumn);
+                        .synchronizedRootResultNodeFromDataRows(rowsColumn);
             }
             else {
                 HierarchicalObjectResolver resolver = new HierarchicalObjectResolver(
                         context,
                         metadata,
-                        descriptor, true);
-                objects = resolver.synchronizedObjectsFromDataRows(
+                        descriptor,
+                        true);
+                return resolver.synchronizedRootResultNodeFromDataRows(
                         prefetchTree,
                         rowsColumn,
                         prefetchResultsByPath);
             }
-            return objects;
         }
 
         @Override
@@ -680,44 +702,47 @@ class DataDomainQueryAction implements Q
 
             List<Object> rsMapping = metadata.getResultSetMapping();
             int width = rsMapping.size();
+
             // no conversions needed for scalar positions; reuse Object[]'s to fill them
             // with resolved objects
-            List<List<?>> resultLists = new ArrayList<List<?>>(width);
+            List<PrefetchProcessorNode> segmentNodes = new ArrayList<PrefetchProcessorNode>(width);
             for (int i = 0; i < width; i++) {
 
                 if (rsMapping.get(i) instanceof EntityResultSegment) {
                     EntityResultSegment entitySegment = (EntityResultSegment) rsMapping
                             .get(i);
-                    List<Persistent> nextResult = toObjects(entitySegment
-                            .getClassDescriptor(), metadata.getPrefetchTree() , mainRows, i);
-                    
-                    resultLists.add(nextResult);
+                    PrefetchProcessorNode nextResult = toResultsTree(
+                            entitySegment.getClassDescriptor(),
+                            metadata.getPrefetchTree(),
+                            mainRows,
+                            i);
+
+                    segmentNodes.add(nextResult);
                     
+                    List<Persistent> objects = nextResult.getObjects();
+
                     for (int j = 0; j < rowsLen; j++) {
                         Object[] row = mainRows.get(j);
-                        row[i] = nextResult.get(j);
+                        row[i] = objects.get(j);
                     }
                 }
             }
             Set<List<?>> seen = new HashSet(mainRows.size());
             Iterator<Object[]> it = mainRows.iterator();
             while (it.hasNext()) {
-                
                 if (!seen.add(Arrays.asList(it.next()))) {
                     it.remove();
-                    
                 }
-                
             }
-            
+
             // invoke callbacks now that all objects are resolved...
             LifecycleCallbackRegistry callbackRegistry = context
                     .getEntityResolver()
                     .getCallbackRegistry();
 
             if (!callbackRegistry.isEmpty(LifecycleEvent.POST_LOAD)) {
-                for (List<?> list : resultLists) {
-                    callbackRegistry.performCallbacks(LifecycleEvent.POST_LOAD, list);
+                for (PrefetchProcessorNode node : segmentNodes) {
+                    performPostLoadCallbacks(node, callbackRegistry);
                 }
             }
         }

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=1033722&r1=1033721&r2=1033722&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 Nov 10 21:32:08 2010
@@ -19,7 +19,6 @@
 
 package org.apache.cayenne.access;
 
-import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
@@ -63,7 +62,7 @@ class HierarchicalObjectResolver {
     /**
      * Properly synchronized version of 'resolveObjectTree'.
      */
-    List synchronizedObjectsFromDataRows(
+    PrefetchProcessorNode synchronizedRootResultNodeFromDataRows(
             PrefetchTreeNode tree,
             List mainResultRows,
             Map extraResultsByPath) {
@@ -75,7 +74,7 @@ class HierarchicalObjectResolver {
         }
     }
 
-    private List resolveObjectTree(
+    private PrefetchProcessorNode resolveObjectTree(
             PrefetchTreeNode tree,
             List mainResultRows,
             Map extraResultsByPath) {
@@ -94,9 +93,7 @@ class HierarchicalObjectResolver {
         // connect related objects
         decoratedTree.traverse(new PostProcessor());
 
-        return decoratedTree.getObjects() != null
-                ? decoratedTree.getObjects()
-                : new ArrayList(1);
+        return decoratedTree;
     }
 
     final class DisjointProcessor implements PrefetchProcessor {

Modified: cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/ObjectResolver.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/ObjectResolver.java?rev=1033722&r1=1033721&r2=1033722&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/ObjectResolver.java (original)
+++ cayenne/main/trunk/framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/ObjectResolver.java Wed Nov 10 21:32:08 2010
@@ -87,6 +87,13 @@ class ObjectResolver {
                 : new NoInheritanceStrategy();
     }
 
+    PrefetchProcessorNode synchronizedRootResultNodeFromDataRows(
+            List<? extends DataRow> rows) {
+        PrefetchProcessorNode rootNode = new PrefetchProcessorNode(null, null);
+        rootNode.setObjects(synchronizedObjectsFromDataRows(rows));
+        return rootNode;
+    }
+
     /**
      * Properly synchronized version of 'objectsFromDataRows'.
      */