This is an automated email from the ASF dual-hosted git repository.
mridulpathak pushed a commit to branch release24.09
in repository https://gitbox.apache.org/repos/asf/ofbiz-framework.git
The following commit(s) were added to refs/heads/release24.09 by this push:
new 0b57ed2660 Keep configurable product selections out of the shared
product config cache
0b57ed2660 is described below
commit 0b57ed2660768ab1b86efcfde1eb3816c6e6f52d
Author: Mridul Pathak <[email protected]>
AuthorDate: Fri Oct 30 14:36:34 2026 +0530
Keep configurable product selections out of the shared product config cache
ProductConfigWorker.getProductConfigWrapper returned the cached
ProductConfigWrapper itself on a cache miss, so the first customer's selections
and comments were written into the cache and copied to every later visitor. It
now always returns a copy. Copies were not independent either: a copied
ConfigOption kept the source option's parent ConfigItem and shared its
componentOptions map, so copied options now belong to the copied item and get
their own map.
---
.../ofbiz/product/config/ProductConfigWorker.java | 20 ++++++++++----------
.../ofbiz/product/config/ProductConfigWrapper.java | 10 +++++++---
2 files changed, 17 insertions(+), 13 deletions(-)
diff --git
a/applications/product/src/main/java/org/apache/ofbiz/product/config/ProductConfigWorker.java
b/applications/product/src/main/java/org/apache/ofbiz/product/config/ProductConfigWorker.java
index 209c93f3d6..65128b5d39 100644
---
a/applications/product/src/main/java/org/apache/ofbiz/product/config/ProductConfigWorker.java
+++
b/applications/product/src/main/java/org/apache/ofbiz/product/config/ProductConfigWorker.java
@@ -68,17 +68,17 @@ public final class ProductConfigWorker {
Delegator delegator = (Delegator)
request.getAttribute("delegator");
String cacheKey = productId + SEPARATOR + productStoreId +
SEPARATOR + catalogId + SEPARATOR + webSiteId + SEPARATOR
+ currencyUomId + SEPARATOR + delegator;
- configWrapper = PRODUCT_CONFIG_CACHE.get(cacheKey);
- if (configWrapper == null) {
- configWrapper = new ProductConfigWrapper((Delegator)
request.getAttribute("delegator"),
- (LocalDispatcher)
request.getAttribute("dispatcher"),
- productId,
productStoreId, catalogId, webSiteId,
- currencyUomId,
UtilHttp.getLocale(request),
- autoUserLogin);
- configWrapper =
PRODUCT_CONFIG_CACHE.putIfAbsentAndGet(cacheKey, new
ProductConfigWrapper(configWrapper));
- } else {
- configWrapper = new ProductConfigWrapper(configWrapper);
+ ProductConfigWrapper cachedWrapper =
PRODUCT_CONFIG_CACHE.get(cacheKey);
+ if (cachedWrapper == null) {
+ cachedWrapper =
PRODUCT_CONFIG_CACHE.putIfAbsentAndGet(cacheKey,
+ new ProductConfigWrapper((Delegator)
request.getAttribute("delegator"),
+ (LocalDispatcher)
request.getAttribute("dispatcher"),
+ productId, productStoreId,
catalogId, webSiteId,
+ currencyUomId,
UtilHttp.getLocale(request),
+ autoUserLogin));
}
+ // callers fill in the customer's selections, so never hand out
the cached instance itself
+ configWrapper = new ProductConfigWrapper(cachedWrapper);
} catch (Exception e) {
Debug.logWarning(e.getMessage(), MODULE);
configWrapper = null;
diff --git
a/applications/product/src/main/java/org/apache/ofbiz/product/config/ProductConfigWrapper.java
b/applications/product/src/main/java/org/apache/ofbiz/product/config/ProductConfigWrapper.java
index 05c0c7bec4..ce8b3e0a74 100644
---
a/applications/product/src/main/java/org/apache/ofbiz/product/config/ProductConfigWrapper.java
+++
b/applications/product/src/main/java/org/apache/ofbiz/product/config/ProductConfigWrapper.java
@@ -518,7 +518,7 @@ public class ProductConfigWrapper implements Serializable {
configItemAssoc = GenericValue.create(ci.configItemAssoc);
options = new LinkedList<>();
for (ConfigOption co: ci.options) {
- options.add(new ConfigOption(co));
+ options.add(new ConfigOption(co, this));
}
first = ci.first;
content = ci.content; // FIXME: this should be cloned
@@ -815,13 +815,17 @@ public class ProductConfigWrapper implements Serializable
{
}
public ConfigOption(ConfigOption co) {
+ this(co, co.parentConfigItem);
+ }
+
+ private ConfigOption(ConfigOption co, ConfigItem parentConfigItem) {
configOption = GenericValue.create(co.configOption);
componentList = new LinkedList<>();
for (GenericValue component: co.componentList) {
componentList.add(GenericValue.create(component));
}
- parentConfigItem = co.parentConfigItem;
- componentOptions = co.componentOptions;
+ this.parentConfigItem = parentConfigItem;
+ componentOptions = co.componentOptions == null ? null : new
HashMap<>(co.componentOptions);
optionListPrice = co.optionListPrice;
optionPrice = co.optionPrice;
available = co.available;