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>