svn commit: r492885 - /db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/core/QueryReferenceBroker.java

[email protected]
Newsgroups gmane.comp.jakarta.ojb.devel
Message-ID <[email protected]>
Author: arminw
Date: Thu Jan  4 19:12:14 2007
New Revision: 492885

URL: http://svn.apache.org/viewvc?view=rev&rev=492885
Log:
improvement to allow enable/disable of proxy prefetching (with boolean setter method)

Modified:
    db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/core/QueryReferenceBroker.java

Modified: db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/core/QueryReferenceBroker.java
URL: http://svn.apache.org/viewvc/db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/core/QueryReferenceBroker.java?view=diff&rev=492885&r1=492884&r2=492885
==============================================================================
--- db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/core/QueryReferenceBroker.java (original)
+++ db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/core/QueryReferenceBroker.java Thu Jan  4 19:12:14 2007
@@ -68,8 +68,7 @@
     private PersistenceBrokerImpl pb;
     private HashMap m_retrievalTasks;
     private ArrayList prefetchingListeners;
-    private final boolean batchRetrieval = true;
-    private final boolean prefetchProxies = true;
+    private boolean prefetchProxies = true;
     private Class classToPrefetch;
     private PBLifeCycleEvent afterLookupEvent;
 
@@ -80,6 +79,24 @@
     }
 
     /**
+     * Return <em>true</em> if proxy object reference pre-fetching is enabled,
+     * <em>false</em> if disabled.
+     */
+    public boolean isPrefetchProxies()
+    {
+        return prefetchProxies;
+    }
+
+    /**
+     * Enable or disable proxy object reference pre-fetching. By default it's enabled.
+     * @param prefetchProxies If set <em>true</em>, reference pre-fetching will be enabled.
+     */
+    public void setPrefetchProxies(boolean prefetchProxies)
+    {
+        this.prefetchProxies = prefetchProxies;
+    }
+
+    /**
      * retrieve a collection of itemClass Objects matching the Query query
      * @param collectionClass type the collection to be returned
      * @param itemClass Class of item in collection
@@ -96,7 +113,7 @@
         int fullSize = -1;
         int size = 0;
 
-        final boolean isRetrievalTasksCreated = batchRetrieval && m_retrievalTasks == null;
+        final boolean isRetrievalTasksCreated = m_retrievalTasks == null;
         if (isRetrievalTasksCreated)
         {
             // Maps ReferenceDescriptors to HashSets of owners
@@ -157,8 +174,8 @@
                             && (cld.getProxyPrefetchingLimit() > 0)
                             && addRetrievalTask(candidate, this))
                     {
-                        new PBMaterializationListener(candidate, m_retrievalTasks,
-                                this, cld.getProxyPrefetchingLimit());
+                        if(log.isDebugEnabled()) log.debug("Add proxy prefetch listener for result candidate of query " + query);
+                        new PBMaterializationListener(candidate, m_retrievalTasks, this, cld.getProxyPrefetchingLimit());
                     }
                 }
             }
@@ -316,24 +333,18 @@
                 Map.Entry entry = (Map.Entry) it.next();
                 Object key = entry.getKey();
 
-                if (!(key instanceof ObjectReferenceDescriptor))
+                if (key instanceof ObjectReferenceDescriptor)
                 {
-                    continue;
-                }
+                    ObjectReferenceDescriptor ord = (ObjectReferenceDescriptor) key;
+                    ArrayList owners = (ArrayList) entry.getValue();
 
-                ObjectReferenceDescriptor ord = (ObjectReferenceDescriptor) key;
-                RelationshipPrefetcher prefetcher;
-                ArrayList owners = (ArrayList) entry.getValue();
-
-//                if (ord instanceof SuperReferenceDescriptor || ord.isLazy() || (ord.getItemProxyClass() != null))
-                if (ord.isLazy() || (ord.getItemProxyClass() != null))
-                {
-                    continue;
+                    if(!ord.isLazy() && (ord.getItemProxyClass() == null))
+                    {
+                        RelationshipPrefetcher prefetcher = pb.getRelationshipPrefetcherFactory().createRelationshipPrefetcher(ord);
+                        prefetcher.prefetchRelationship(owners);
+                        it.remove();
+                    }
                 }
-
-                prefetcher = pb.getRelationshipPrefetcherFactory().createRelationshipPrefetcher(ord);
-                prefetcher.prefetchRelationship(owners);
-                it.remove();
             }
         }
     }
@@ -341,26 +352,26 @@
     /**
      * Retrieve a single Reference.
      * This implementation retrieves a referenced object from the data backend
-     * if <b>cascade-retrieve</b> is true or if <b>forced</b> is true.
+     * if <b>cascade-retrieve</b> is true or if <b>forceReference</b> is true.
      *
      * @param obj - object that will have it's field set with a referenced object.
      * @param cld - the ClassDescriptor describring obj
      * @param rds - the ObjectReferenceDescriptor of the reference attribute to be loaded
-     * @param forced - if set to true, the reference is loaded even if the rds differs.
+     * @param forceReference if set to true, loading of reference is forced even if cld
+     * auto/cascade retrieve setting differs
      */
-    public void retrieveReference(Object obj, ClassDescriptor cld, ObjectReferenceDescriptor rds, boolean forced)
+    public void retrieveReference(Object obj, ClassDescriptor cld, ObjectReferenceDescriptor rds, boolean forceReference)
     {
         PersistentField refField;
         Object refObj = null;
 
-        if (forced || rds.getCascadeRetrieve())
+        if (forceReference || rds.getCascadeRetrieve())
         {
             pb.getInternalCache().enableMaterializationCache();
             try
             {
                 Identity id = getReferencedObjectIdentity(obj, rds, cld);
                 boolean isRefObjDefined = true;
-
                 if (id == null)
                 {
                     refObj = null;
@@ -371,14 +382,12 @@
                     if (rds.isSuperReferenceDescriptor())
                     {
                         // walk the super-references
-                        ClassDescriptor superCld = cld.getRepository().getDescriptorFor(rds.getItemClass());
+                        ClassDescriptor superCld = cld.getSuperClassDescriptor();
                         retrieveReferences(refObj, superCld, false);
                         retrieveCollections(refObj, superCld, false);
                     }
                 }
-                else if ((m_retrievalTasks != null)
-                        && !rds.isLazy()
-                        && (rds.getItemProxyClass() == null))
+                else if ((m_retrievalTasks != null) && !rds.isLazy() && (rds.getItemProxyClass() == null))
                 {
                     addRetrievalTask(obj, rds);
                     isRefObjDefined = false;
@@ -386,6 +395,7 @@
                 else
                 {
                     refObj = getReferencedObject(id, rds);
+                    if(refObj == null) isRefObjDefined = false;
                 }
 
                 if (isRefObjDefined)
@@ -393,17 +403,14 @@
                     refField = rds.getPersistentField();
                     refField.set(obj, refObj);
 
-                    if ((refObj != null) && prefetchProxies
-                            && (m_retrievalTasks != null)
+                    if ((refObj != null) && prefetchProxies && (m_retrievalTasks != null)
                             && (rds.getProxyPrefetchingLimit() > 0))
                     {
                         IndirectionHandler handler = pb.getProxyFactory().getIndirectionHandler(refObj);
-
-                        if ((handler != null)
-                                && addRetrievalTask(obj, rds))
+                        if ((handler != null) && addRetrievalTask(obj, rds))
                         {
-                            new PBMaterializationListener(obj, m_retrievalTasks,
-                                    rds, rds.getProxyPrefetchingLimit());
+                            if(log.isDebugEnabled()) log.debug("Add proxy prefetch listener for reference " + rds);
+                            new PBMaterializationListener(obj, m_retrievalTasks, rds, rds.getProxyPrefetchingLimit());
                         }
                     }
                 }
@@ -421,43 +428,39 @@
     /**
      * Retrieve a single Reference.
      * This implementation retrieves a referenced object from the data backend
-     * if <b>cascade-retrieve</b> is true or if <b>forced</b> is true.
+     * if <b>cascade-retrieve</b> is true or if <b>forceReference</b> is true.
      *
      * @param obj - object that will have it's field set with a referenced object.
      * @param cld - the ClassDescriptor describring obj
      * @param rds - the ObjectReferenceDescriptor of the reference attribute to be loaded
-     * @param forced - if set to true, the reference is loaded even if the rds differs.
+     * @param forceReference if set to true, loading of reference is forced even if cld
+     * auto/cascade retrieve setting differs
      */
-    public void retrieveProxyReference(Object obj, ClassDescriptor cld, ObjectReferenceDescriptor rds, boolean forced)
+    public void retrieveProxyReference(Object obj, ClassDescriptor cld, ObjectReferenceDescriptor rds, boolean forceReference)
     {
         PersistentField refField;
         Object refObj = null;
-
             pb.getInternalCache().enableMaterializationCache();
             try
             {
                 Identity id = getReferencedObjectIdentity(obj, rds, cld);
-                if (id != null){
+                if (id != null)
+                {
                     refObj = pb.createProxy(rds.getItemClass(), id);
                 }
                 refField = rds.getPersistentField();
                 refField.set(obj, refObj);
 
-                if ((refObj != null) && prefetchProxies
-                        && (m_retrievalTasks != null)
+                if ((refObj != null) && prefetchProxies && (m_retrievalTasks != null)
                         && (rds.getProxyPrefetchingLimit() > 0))
                 {
                     IndirectionHandler handler = pb.getProxyFactory().getIndirectionHandler(refObj);
-
-                    if ((handler != null)
-                            && addRetrievalTask(obj, rds))
+                    if ((handler != null) && addRetrievalTask(obj, rds))
                     {
-                        new PBMaterializationListener(obj, m_retrievalTasks,
-                                rds, rds.getProxyPrefetchingLimit());
+                        if(log.isDebugEnabled()) log.debug("Add proxy prefetch listener for reference " + rds);
+                        new PBMaterializationListener(obj, m_retrievalTasks, rds, rds.getProxyPrefetchingLimit());
                     }
                 }
-
-
                 pb.getInternalCache().disableMaterializationCache();
             }
             catch(RuntimeException e)
@@ -473,12 +476,12 @@
      *
      * @param newObj the instance to be loaded or refreshed
      * @param cld the ClassDescriptor of the instance
-     * @param forced if set to true loading is forced even if cld differs.
+     * @param forceReference if set to true, loading of reference is forced even if cld
+     * auto/cascade retrieve setting differs
      */
-    public void retrieveReferences(Object newObj, ClassDescriptor cld, boolean forced) throws PersistenceBrokerException
+    public void retrieveReferences(Object newObj, ClassDescriptor cld, boolean forceReference) throws PersistenceBrokerException
     {
         Iterator i = cld.getObjectReferenceDescriptors().iterator();
-
         // turn off auto prefetching for related proxies
         final Class saveClassToPrefetch = classToPrefetch;
         classToPrefetch = null;
@@ -489,9 +492,8 @@
             while (i.hasNext())
             {
                 ObjectReferenceDescriptor rds = (ObjectReferenceDescriptor) i.next();
-                retrieveReference(newObj, cld, rds, forced);
+                retrieveReference(newObj, cld, rds, forceReference);
             }
-
             pb.getInternalCache().disableMaterializationCache();
         }
         catch(RuntimeException e)
@@ -510,12 +512,12 @@
      *
      * @param newObj the instance to be loaded or refreshed
      * @param cld the ClassDescriptor of the instance
-     * @param forced if set to true loading is forced even if cld differs.
+     * @param forceReference if set to true, loading of reference is forced even if cld
+     * auto/cascade retrieve setting differs
      */
-    public void retrieveProxyReferences(Object newObj, ClassDescriptor cld, boolean forced) throws PersistenceBrokerException
+    public void retrieveProxyReferences(Object newObj, ClassDescriptor cld, boolean forceReference) throws PersistenceBrokerException
     {
         Iterator i = cld.getObjectReferenceDescriptors().iterator();
-
         // turn off auto prefetching for related proxies
         final Class saveClassToPrefetch = classToPrefetch;
         classToPrefetch = null;
@@ -526,9 +528,8 @@
             while (i.hasNext())
             {
                 ObjectReferenceDescriptor rds = (ObjectReferenceDescriptor) i.next();
-                retrieveProxyReference(newObj, cld, rds, forced);
+                retrieveProxyReference(newObj, cld, rds, forceReference);
             }
-
             pb.getInternalCache().disableMaterializationCache();
         }
         catch(RuntimeException e)
@@ -574,7 +575,8 @@
         else
         {
             // ensure that top-level extents are used for Identities
-            return pb.serviceIdentity().buildIdentity(rds.getItemClass(), pb.getTopLevelClass(rds.getItemClass()), fkValues);
+            return pb.serviceIdentity().buildIdentity(rds.getItemClass(),
+                    rds.getItemClassDescriptor().getTopLevelClass(), fkValues);
         }
         return null;
     }
@@ -663,33 +665,34 @@
     /**
      * Retrieve a single Collection on behalf of <b>obj</b>.
      * The Collection is retrieved only if <b>cascade.retrieve is true</b>
-     * or if <b>forced</b> is set to true.     *
+     * or if <b>forceReference</b> is set to true.     *
      *
      * @param obj - the object to be updated
      * @param cld - the ClassDescriptor describing obj
      * @param cds - the CollectionDescriptor describing the collection attribute to be loaded
-     * @param forced - if set to true loading is forced, even if cds differs.
+     * @param forceReference - if set to true loading is forced, even if cds differs.
      *
      */
-    public void retrieveCollection(Object obj, ClassDescriptor cld, CollectionDescriptor cds, boolean forced)
+    public void retrieveCollection(Object obj, ClassDescriptor cld, CollectionDescriptor cds, boolean forceReference)
     {
-        doRetrieveCollection(obj, cds, forced, cds.isLazy());
+        doRetrieveCollection(obj, cds, forceReference, cds.isLazy());
     }
 
     /**
      * Retrieve a single Proxied Collection on behalf of <b>obj</b>.
      * The Collection is retrieved only if <b>cascade.retrieve is true</b>
-     * or if <b>forced</b> is set to true.     *
+     * or if <b>forceReference</b> is set to true.     *
      *
      * @param obj - the object to be updated
      * @param cld - the ClassDescriptor describing obj
      * @param cds - the CollectionDescriptor describing the collection attribute to be loaded
-     * @param forced - if set to true a proxy will be placed, even if cds differs.
+     * @param forceReference if set to true, loading of reference is forced even if cld
+     * auto/cascade retrieve setting differs
      *
      */
-    public void retrieveProxyCollection(Object obj, ClassDescriptor cld, CollectionDescriptor cds, boolean forced)
+    public void retrieveProxyCollection(Object obj, ClassDescriptor cld, CollectionDescriptor cds, boolean forceReference)
     {
-        doRetrieveCollection(obj, cds, forced, true);
+        doRetrieveCollection(obj, cds, forceReference, true);
     }
 
     private void doRetrieveCollection(Object obj, CollectionDescriptor cds, boolean forced, boolean lazyLoad)
@@ -697,8 +700,7 @@
         if (forced || cds.getCascadeRetrieve())
         {
             if ((m_retrievalTasks != null) && !cds.isLazy()
-                    && !cds.hasProxyItems()
-                    && (cds.getQueryCustomizer() == null))
+                    && !cds.hasProxyItems() && (cds.getQueryCustomizer() == null))
             {
                 addRetrievalTask(obj, cds);
             }
@@ -745,8 +747,8 @@
                     {
                         if (addRetrievalTask(obj, cds))
                         {
-                            new PBCollectionProxyListener(obj,
-                                    m_retrievalTasks, cds, cds.getProxyPrefetchingLimit());
+                            if(log.isDebugEnabled()) log.debug("Add proxy prefetch listener for collection reference " + cds);
+                            new PBCollectionProxyListener(obj, m_retrievalTasks, cds, cds.getProxyPrefetchingLimit());
                         }
                     }
 
@@ -803,18 +805,19 @@
     }
 
     /**
-     * Get Foreign key query for m:n <br>
-     * supports UNIDIRECTIONAL m:n using QueryByMtoNCriteria
-     * @return org.apache.ojb.broker.query.QueryByCriteria
+     * Get Foreign key query for m:n relationship
+     * supports UNIDIRECTIONAL m:n using QueryByMtoNCriteria.
+     *
      * @param obj the owner of the relationship
      * @param cod the CollectionDescriptor
+     * @return A Query object
      */
     private QueryByCriteria getFKQueryMtoN(Object obj, CollectionDescriptor cod)
     {
         ValueContainer[] values = pb.serviceBrokerHelper().getFkTargetValuesForObject(cod, obj ,false);
         Object[] thisClassFks = cod.getFksToThisClass();
         Object[] itemClassFks = cod.getFksToItemClass();
-        ClassDescriptor refCld = pb.getClassDescriptor(cod.getItemClass());
+        ClassDescriptor refCld = cod.getItemClassDescriptor();
         Criteria criteria = new Criteria();
 
         for (int i = 0; i < thisClassFks.length; i++)
@@ -831,24 +834,22 @@
     }
 
     /**
-     * Get Foreign key query for 1:n
+     * Get Foreign key query for 1:n relationship.
+     *
+     * @param obj the owner of the relationship
+     * @param cod the CollectionDescriptor
      * @return org.apache.ojb.broker.query.QueryByCriteria
-     * @param obj
-     * @param cod
      */
     private QueryByCriteria getFKQuery1toN(Object obj, CollectionDescriptor cod)
     {
         ValueContainer[]  container = pb.serviceBrokerHelper().getFkTargetValuesForObject(cod, obj ,false);
-        ClassDescriptor refCld = pb.getClassDescriptor(cod.getItemClass());
+        ClassDescriptor refCld = cod.getItemClassDescriptor();
         FieldDescriptor[] fields = cod.getForeignKeyFieldDescriptors(refCld);
         Criteria criteria = new Criteria();
-
         for (int i = 0; i < fields.length; i++)
         {
-            FieldDescriptor fld = fields[i];
-            criteria.addEqualTo(fld.getAttributeName(), container[i].getValue());
+            criteria.addEqualTo(fields[i].getAttributeName(), container[i].getValue());
         }
-
         return QueryFactory.newQuery(refCld.getClassOfObject(), criteria);
     }
 
@@ -885,12 +886,13 @@
      *
      * @param newObj the instance to be loaded or refreshed
      * @param cld the ClassDescriptor of the instance
-     * @param forced if set to true, loading is forced even if cld differs
+     * @param forceReference if set to true, loading of reference is forced even if cld
+     * auto/cascade retrieve setting differs
      *
      */
-    public void retrieveCollections(Object newObj, ClassDescriptor cld, boolean forced) throws PersistenceBrokerException
+    public void retrieveCollections(Object newObj, ClassDescriptor cld, boolean forceReference) throws PersistenceBrokerException
     {
-        doRetrieveCollections(newObj, cld, forced, false);
+        doRetrieveCollections(newObj, cld, forceReference, false);
     }
 
     /**
@@ -898,15 +900,16 @@
      *
      * @param newObj the instance to be loaded or refreshed
      * @param cld the ClassDescriptor of the instance
-     * @param forced if set to true, loading is forced even if cld differs
+     * @param forceReference if set to true, loading of reference is forced even if cld
+     * auto/cascade retrieve setting differs
      *
      */
-    public void retrieveProxyCollections(Object newObj, ClassDescriptor cld, boolean forced) throws PersistenceBrokerException
+    public void retrieveProxyCollections(Object newObj, ClassDescriptor cld, boolean forceReference) throws PersistenceBrokerException
     {
-        doRetrieveCollections(newObj, cld, forced, true);
+        doRetrieveCollections(newObj, cld, forceReference, true);
     }
 
-    private void doRetrieveCollections(Object newObj, ClassDescriptor cld, boolean forced, boolean forceProxyCollection) throws PersistenceBrokerException
+    private void doRetrieveCollections(Object newObj, ClassDescriptor cld, boolean forceReference, boolean forceProxyCollection) throws PersistenceBrokerException
     {
         Iterator i = cld.getCollectionDescriptors().iterator();
 
@@ -920,10 +923,13 @@
             while (i.hasNext())
             {
                 CollectionDescriptor cds = (CollectionDescriptor) i.next();
-                if (forceProxyCollection){
-                    retrieveProxyCollection(newObj, cld, cds, forced);
-                } else {
-                    retrieveCollection(newObj, cld, cds, forced);
+                if (forceProxyCollection)
+                {
+                    retrieveProxyCollection(newObj, cld, cds, forceReference);
+                }
+                else
+                {
+                    retrieveCollection(newObj, cld, cds, forceReference);
                 }
             }
             pb.getInternalCache().disableMaterializationCache();
@@ -956,6 +962,11 @@
         }
     }
 
+    /**
+     * Return the Class to be prefetched.
+     *
+     * @return Class or null.
+     */
     public Class getClassToPrefetch()
     {
         return classToPrefetch;
@@ -969,8 +980,7 @@
     {
         private IndirectionHandler _listenedHandler;
 
-        PBMaterializationListener(Object owner,
-                                  HashMap retrievalTasks, Object key, int limit)
+        PBMaterializationListener(Object owner, HashMap retrievalTasks, Object key, int limit)
         {
             super(owner, retrievalTasks, key, limit);
         }
@@ -1026,8 +1036,7 @@
         private int _limit;
         protected Object _key;
 
-        PBPrefetchingListener(Object owner, HashMap retrievalTasks,
-                              Object key, int limit)
+        PBPrefetchingListener(Object owner, HashMap retrievalTasks, Object key, int limit)
         {
             _retrievalTasks = retrievalTasks;
             _key = key;
@@ -1069,6 +1078,7 @@
             }
             else
             {
+                if(log.isDebugEnabled()) log.debug("Prefetch limit of " + _limit + " entries rearched");
                 toPrefetch = owners.subList(0, _limit);
                 prefetchingAll = false;
             }
@@ -1077,6 +1087,7 @@
             classToPrefetch = prefetcher.getItemClassDescriptor().getClassOfObject();
             try
             {
+                if(log.isDebugEnabled()) log.debug("Start prefetching of objects for " + prefetcher);
                 prefetcher.prefetchRelationship(toPrefetch);
             }
             finally
@@ -1086,10 +1097,12 @@
 
             if (prefetchingAll)
             {
+                if(log.isDebugEnabled()) log.debug("All objects for key " + _key + " prefetched");
                 _retrievalTasks.remove(_key);
             }
             else
             {
+                if(log.isDebugEnabled()) log.debug("Only objects till limit prefetched for key " + _key);
                 // ArrayList documented trick:
                 // "the following idiom removes a range of elements from a list:
                 // list.subList(from, to).clear();
@@ -1099,21 +1112,18 @@
         }
     }
 
-    class PBCollectionProxyListener extends PBPrefetchingListener
-            implements CollectionProxyListener
+    class PBCollectionProxyListener extends PBPrefetchingListener implements CollectionProxyListener
     {
         CollectionProxyDefaultImpl _listenedCollection;
 
-        PBCollectionProxyListener(Object owner,
-                                  HashMap retrievalTasks, CollectionDescriptor key, int limit)
+        PBCollectionProxyListener(Object owner, HashMap retrievalTasks, CollectionDescriptor key, int limit)
         {
             super(owner, retrievalTasks, key, limit);
         }
 
         protected void addThisListenerTo(Object owner)
         {
-            PersistentField collectionField =
-                    ((CollectionDescriptor) _key).getPersistentField();
+            PersistentField collectionField = ((CollectionDescriptor) _key).getPersistentField();
             _listenedCollection = (CollectionProxyDefaultImpl) collectionField.get(owner);
             _listenedCollection.addListener(this);
         }
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.