This is an automated email from the ASF dual-hosted git repository.

mleila pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/ofbiz-framework.git


The following commit(s) were added to refs/heads/trunk by this push:
     new 0748e67e5e Fixed: Issue when caching a query with a selectField 
(OFBIZ-13072) (#787)
0748e67e5e is described below

commit 0748e67e5eee689425bcb08f73024d659b7007a2
Author: MLeila <mle...@apache.org>
AuthorDate: Thu May 2 09:44:48 2024 +0200

    Fixed: Issue when caching a query with a selectField (OFBIZ-13072) (#787)
    
    When a query with a field selection and a cache() option is done, the
    result is put in cache with the incomplete genericValue (I mean without
    all the fields).
    
    Then when an other query with the same condition and cache option is
    done, even whitout the field selection, the result returned is the
    incomplete version of the GenericValue that has been stored in cache.
    
    This prevent from adding in cache an incomplete genericValue and filter
    the cached value when necessary
---
 .../org/apache/ofbiz/entity/GenericDelegator.java  |  2 +-
 .../ofbiz/entity/test/EntityQueryTestSuite.java    | 38 ++++++++++++++++++++++
 .../org/apache/ofbiz/entity/util/EntityQuery.java  |  5 ++-
 .../org/apache/ofbiz/entity/util/EntityUtil.java   | 15 +++++++++
 4 files changed, 58 insertions(+), 2 deletions(-)

diff --git 
a/framework/entity/src/main/java/org/apache/ofbiz/entity/GenericDelegator.java 
b/framework/entity/src/main/java/org/apache/ofbiz/entity/GenericDelegator.java
index 1ad455082c..512a3634d6 100644
--- 
a/framework/entity/src/main/java/org/apache/ofbiz/entity/GenericDelegator.java
+++ 
b/framework/entity/src/main/java/org/apache/ofbiz/entity/GenericDelegator.java
@@ -1649,7 +1649,7 @@ public class GenericDelegator implements Delegator {
                 list = eli.getCompleteList();
             }
 
-            if (useCache) {
+            if (useCache && UtilValidate.isEmpty(fieldsToSelect)) {
                 ecaRunner.evalRules(EntityEcaHandler.EV_CACHE_PUT, 
EntityEcaHandler.OP_FIND, dummyValue, false);
                 this.cache.put(entityName, entityCondition, orderBy, list);
             }
diff --git 
a/framework/entity/src/main/java/org/apache/ofbiz/entity/test/EntityQueryTestSuite.java
 
b/framework/entity/src/main/java/org/apache/ofbiz/entity/test/EntityQueryTestSuite.java
index b0d55db27c..66b16f542d 100644
--- 
a/framework/entity/src/main/java/org/apache/ofbiz/entity/test/EntityQueryTestSuite.java
+++ 
b/framework/entity/src/main/java/org/apache/ofbiz/entity/test/EntityQueryTestSuite.java
@@ -18,6 +18,7 @@
  
*******************************************************************************/
 package org.apache.ofbiz.entity.test;
 
+import java.sql.Timestamp;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
@@ -469,6 +470,43 @@ public class EntityQueryTestSuite extends EntityTestCase {
         }
     }
 
+    /**
+     * testCache(): When cache() is activated, the result of a query is set to 
cache for a given condition.
+     * assert: Ensure that a request with a select or a date filter stored in 
cache is not retrieved by a query
+     * without select nor date filter having the same condition.
+     */
+    public void testCache() throws GenericEntityException {
+        Timestamp now = UtilDateTime.nowTimestamp();
+        Delegator delegator = getDelegator();
+
+        delegator.create("TestingType", "testingTypeId", "cacheWithSelect", 
"description", "cache with selection One");
+        delegator.create("TestingType", "testingTypeId", "cacheWithDate", 
"description", "cache with filterByDate One");
+
+        delegator.create("TestingNode", "testingNodeId", "testingCacheNode1");
+        delegator.create("TestingNode", "testingNodeId", "testingCacheNode2");
+
+        delegator.create("Testing", "testingId", "testingCache1", 
"testingTypeId", "cacheWithDate");
+
+        delegator.create("TestingNodeMember", "testingNodeId", 
"testingCacheNode1", "testingId", "testingCache1", "fromDate",
+                        now, "thruDate", UtilDateTime.getNextDayStart(now));
+        delegator.create("TestingNodeMember", "testingNodeId", 
"testingCacheNode2", "testingId", "testingCache1", "fromDate",
+                        now, "thruDate", now);
+
+        List<GenericValue> cachedResultWithFilterByDate = 
EntityQuery.use(delegator).from("TestingNodeMember").filterByDate()
+                .where("testingId", "testingCache1").cache().queryList();
+        assertEquals("testCache(): Number of records found match", 1, 
cachedResultWithFilterByDate.size());
+
+        List<GenericValue> cachedResultWithoutFilterByDate = 
EntityQuery.use(delegator).from("TestingNodeMember")
+                .where("testingId", "testingCache1").queryList();
+        assertEquals("testCache(): Number of records found match", 2, 
cachedResultWithoutFilterByDate.size());
+
+        GenericValue firstCachedResultWithSelect = 
EntityQuery.use(delegator).select("testingTypeId").from("TestingType").cache().queryFirst();
+        assertFalse(firstCachedResultWithSelect.containsKey("description"));
+
+        GenericValue secondCachedResultWithSelect = 
EntityQuery.use(delegator).from("TestingType").cache().queryFirst();
+        assertTrue(secondCachedResultWithSelect.containsKey("description"));
+    }
+
     /**
      * cursorScrollInSensitive(): ResultSet object's cursor is scrollable but 
generally not sensitive to changes to the data that
      * underlies the ResultSet.
diff --git 
a/framework/entity/src/main/java/org/apache/ofbiz/entity/util/EntityQuery.java 
b/framework/entity/src/main/java/org/apache/ofbiz/entity/util/EntityQuery.java
index 8a63d31398..8da955250c 100644
--- 
a/framework/entity/src/main/java/org/apache/ofbiz/entity/util/EntityQuery.java
+++ 
b/framework/entity/src/main/java/org/apache/ofbiz/entity/util/EntityQuery.java
@@ -473,7 +473,10 @@ public class EntityQuery {
             }
         }
         if (filterByDate && useCache) {
-            return EntityUtil.filterByCondition(result, 
this.makeDateCondition());
+            result = EntityUtil.filterByCondition(result, 
this.makeDateCondition());
+        }
+        if (UtilValidate.isNotEmpty(fieldsToSelect) && useCache) {
+            result = 
EntityUtil.getSelectedFieldValueListFromEntityList(delegator, result, 
fieldsToSelect);
         }
         return result;
     }
diff --git 
a/framework/entity/src/main/java/org/apache/ofbiz/entity/util/EntityUtil.java 
b/framework/entity/src/main/java/org/apache/ofbiz/entity/util/EntityUtil.java
index 8eb0b30c8a..bfbd36ce76 100644
--- 
a/framework/entity/src/main/java/org/apache/ofbiz/entity/util/EntityUtil.java
+++ 
b/framework/entity/src/main/java/org/apache/ofbiz/entity/util/EntityUtil.java
@@ -512,6 +512,21 @@ public final class EntityUtil {
         return fieldList;
     }
 
+    /**
+     * returns the values with the matching selected fields
+     * @param delegator
+     * @param values List of GenericValues
+     * @param selected  the lit of selected fields
+     * @return List of GenericValue's with only selected fields
+     */
+    public static List<GenericValue> 
getSelectedFieldValueListFromEntityList(Delegator delegator, List<GenericValue> 
values, Set<String> selected) {
+        if (values == null || UtilValidate.isEmpty(selected)) {
+            return values;
+        }
+        return values.stream()
+                .map(value -> delegator.makeValidValue(value.getEntityName(), 
value.getFields(selected))).collect(toList());
+    }
+
     /**
      * Returns <code>true</code> if multi-tenant has been enabled.
      * <p>Multi-tenant features are enabled by setting the 
<code>multitenant</code>

Reply via email to