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
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 1ad4550..512a363 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 @@
                 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 b0d55db..66b16f5 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;
@@ -470,6 +471,43 @@
     }
 
     /**
+     * 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.
      * assert: Compared first record found by both the iterators.
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 8a63d31..8da9552 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 @@
             }
         }
         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 8eb0b30..bfbd36c 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
@@ -513,6 +513,21 @@
     }
 
     /**
+     * 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>
      * property in <code>general.properties</code> to "Y".</p>