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

asf-gitbox-commits pushed a commit to branch past-M2
in repository https://gitbox.apache.org/repos/asf/cayenne.git

commit 8dc259abcf5812ad0ee589e697568814e8769593
Author: Andrus Adamchik <[email protected]>
AuthorDate: Sun Jun 7 11:31:21 2026 -0400

    QueryMetadata cleanup
    
    * QueryMetadataWrapper is entirely unneeded
---
 .../cayenne/access/DataDomainQueryAction.java      |  53 ++++-----
 .../java/org/apache/cayenne/query/QueryChain.java  |   9 +-
 .../apache/cayenne/query/QueryMetadataWrapper.java | 128 ---------------------
 .../org/apache/cayenne/query/RefreshQuery.java     |  21 ++--
 4 files changed, 41 insertions(+), 170 deletions(-)

diff --git 
a/cayenne/src/main/java/org/apache/cayenne/access/DataDomainQueryAction.java 
b/cayenne/src/main/java/org/apache/cayenne/access/DataDomainQueryAction.java
index 6858c3f63..ed842df51 100644
--- a/cayenne/src/main/java/org/apache/cayenne/access/DataDomainQueryAction.java
+++ b/cayenne/src/main/java/org/apache/cayenne/access/DataDomainQueryAction.java
@@ -77,7 +77,7 @@ import java.util.function.Function;
  * Performs query routing and execution. During execution phase intercepts
  * callbacks to the OperationObserver, remapping results to the original
  * pre-routed queries.
- * 
+ *
  * @since 1.2
  */
 class DataDomainQueryAction implements QueryRouter, OperationObserver {
@@ -452,11 +452,11 @@ class DataDomainQueryAction implements QueryRouter, 
OperationObserver {
             // response may already be initialized by the factory above ...
             // it is null if there was a preexisting cache entry
             cacheHit = (response == null);
-            
+
             if (response == null || wasResponseNull) {
                 response = new ListResponse(cachedResults);
             }
-            
+
             // Mark as cached result - lists need copying whether hit or miss
             cachedResult = true;
 
@@ -545,12 +545,12 @@ class DataDomainQueryAction implements QueryRouter, 
OperationObserver {
         ObjectConversionStrategy<?, ?> converter = getConverter();
         // local copy because it can change while iterating
         QueryResponse response = this.response;
-        for (response.reset(); response.next();) {
+        for (response.reset(); response.next(); ) {
             if (response.isList()) {
                 List<?> mainRows = response.currentList(); // List<DataRow> or 
List<Object[]>
                 if (mainRows != null && !mainRows.isEmpty()) {
                     List<?> result = converter.convert((List) mainRows);
-                    if(result != mainRows) {
+                    if (result != mainRows) {
                         updateResponse(mainRows, result);
                     }
                 }
@@ -735,15 +735,14 @@ class DataDomainQueryAction implements QueryRouter, 
OperationObserver {
                         
.synchronizedRootResultNodeFromDataRows(normalizedRows);
             } else {
                 // When results come from cache (not a refresh operation), 
wrap metadata to prevent refreshing objects
-                QueryMetadata effectiveMetadata = shouldSkipRefresh() && 
metadata.isRefreshingObjects() 
-                        ? new NonRefreshingQueryMetadataWrapper(metadata)
+                QueryMetadata effectiveMetadata = shouldSkipRefresh() && 
metadata.isRefreshingObjects()
+                        ? nonRefreshingMetadata(metadata)
                         : metadata;
-                HierarchicalObjectResolver resolver = new 
HierarchicalObjectResolver(context, effectiveMetadata);
-                return resolver
+                return new HierarchicalObjectResolver(context, 
effectiveMetadata)
                         .synchronizedRootResultNodeFromDataRows(prefetchTree, 
normalizedRows, prefetchResultsByPath);
             }
         }
-        
+
         private boolean shouldSkipRefresh() {
             // Skip refresh only for cache hits to prevent stale cached data 
from clobbering newer in-memory state
             // For cache misses (including explicit refresh operations), 
cacheHit is false, so refresh happens normally
@@ -766,6 +765,15 @@ class DataDomainQueryAction implements QueryRouter, 
OperationObserver {
         }
     }
 
+    private QueryMetadata nonRefreshingMetadata(QueryMetadata metadata) {
+        return new QueryMetadataProxy(metadata) {
+            @Override
+            public boolean isRefreshingObjects() {
+                return false;
+            }
+        };
+    }
+
     class SingleObjectConversionStrategy extends 
ObjectConversionStrategy<DataRow, Persistent> {
 
         @Override
@@ -865,7 +873,7 @@ class DataDomainQueryAction implements QueryRouter, 
OperationObserver {
             List<Object[]> result = createResultList(mainRows, needConversion);
 
             // no conversions needed for scalar positions;
-            if(needConversion) {
+            if (needConversion) {
                 // reuse Object[]'s to fill them with resolved objects
                 List<PrefetchProcessorNode> segmentNodes = 
doInPlaceConversion(result);
 
@@ -895,19 +903,19 @@ class DataDomainQueryAction implements QueryRouter, 
OperationObserver {
         }
 
         private List<Object[]> createResultList(List<Object[]> mainRows, 
boolean needConversion) {
-            if(!cachedResult) {
+            if (!cachedResult) {
                 // fast-path, we can reuse existing rows
                 return mainRows;
             }
 
-            if(!needConversion) {
+            if (!needConversion) {
                 // no conversion needed, so can clone only top-level list
                 return new ArrayList<>(mainRows);
             }
 
             // slowest path, deep copy everything
             List<Object[]> result = new ArrayList<>(mainRows.size());
-            for(Object[] row : mainRows) {
+            for (Object[] row : mainRows) {
                 result.add(Arrays.copyOf(row, 
metadata.getResultSetMapping().size()));
             }
             return result;
@@ -949,7 +957,7 @@ class DataDomainQueryAction implements QueryRouter, 
OperationObserver {
         private List<PrefetchProcessorNode> doInPlaceConversion(List<Object[]> 
result) {
             List<Object> resultSetMapping = metadata.getResultSetMapping();
             int width = resultSetMapping.size();
-            int height  = result.size();
+            int height = result.size();
             List<PrefetchProcessorNode> segmentNodes = new ArrayList<>(width);
             for (int i = 0; i < width; i++) {
                 Object mapping = resultSetMapping.get(i);
@@ -1035,19 +1043,4 @@ class DataDomainQueryAction implements QueryRouter, 
OperationObserver {
             return mapper.apply(parentStrategy.convert(object));
         }
     }
-
-    /**
-     * Wrapper that overrides isRefreshingObjects() to return false, 
preventing cached
-     * query results from clobbering newer in-memory object state.
-     */
-    static class NonRefreshingQueryMetadataWrapper extends QueryMetadataProxy {
-        NonRefreshingQueryMetadataWrapper(QueryMetadata delegate) {
-            super(delegate);
-        }
-
-        @Override
-        public boolean isRefreshingObjects() {
-            return false;
-        }
-    }
 }
diff --git a/cayenne/src/main/java/org/apache/cayenne/query/QueryChain.java 
b/cayenne/src/main/java/org/apache/cayenne/query/QueryChain.java
index 37fd17dc5..d2419d045 100644
--- a/cayenne/src/main/java/org/apache/cayenne/query/QueryChain.java
+++ b/cayenne/src/main/java/org/apache/cayenne/query/QueryChain.java
@@ -110,8 +110,11 @@ public class QueryChain implements Query {
      * Returns default metadata.
      */
     public QueryMetadata getMetaData(EntityResolver resolver) {
-        QueryMetadataWrapper wrapper = new 
QueryMetadataWrapper(DefaultQueryMetadata.defaultMetadata);
-        wrapper.override(QueryMetadata.FETCHING_DATA_ROWS_PROPERTY, 
Boolean.TRUE);
-        return wrapper;
+        return new QueryMetadataProxy(DefaultQueryMetadata.defaultMetadata) {
+            @Override
+            public boolean isFetchingDataRows() {
+                return true;
+            }
+        };
     }
 }
diff --git 
a/cayenne/src/main/java/org/apache/cayenne/query/QueryMetadataWrapper.java 
b/cayenne/src/main/java/org/apache/cayenne/query/QueryMetadataWrapper.java
deleted file mode 100644
index fd255e258..000000000
--- a/cayenne/src/main/java/org/apache/cayenne/query/QueryMetadataWrapper.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/*****************************************************************
- *   Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *    https://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- ****************************************************************/
-
-package org.apache.cayenne.query;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * A wrapper for a QueryMetadata instance allowing that may override a subset 
of metadata
- * properties.
- * 
- * @since 1.2
- */
-class QueryMetadataWrapper extends QueryMetadataProxy {
-
-    static final String CACHE_KEY_PROPERTY = "QueryMetadataWrapper.CacheKey";
-
-    Map<String, Object> overrides;
-
-    public QueryMetadataWrapper(QueryMetadata info) {
-        super(info);
-    }
-
-    /**
-     * Overrides a property with an alternative value. Property names are 
defined in the
-     * {@link QueryMetadata} interface.
-     */
-    void override(String key, Object value) {
-        if (overrides == null) {
-            overrides = new HashMap<>();
-        }
-
-        overrides.put(key, value);
-    }
-
-    boolean overrideExists(String key) {
-        return overrides != null && overrides.containsKey(key);
-    }
-
-    public String getCacheKey() {
-        return (overrideExists(CACHE_KEY_PROPERTY))
-                ? (String) overrides.get(CACHE_KEY_PROPERTY)
-                : super.getCacheKey();
-    }
-
-    /**
-     * @since 3.0
-     */
-    public QueryCacheStrategy getCacheStrategy() {
-        return (overrideExists(QueryMetadata.CACHE_STRATEGY_PROPERTY))
-                ? (QueryCacheStrategy) 
overrides.get(QueryMetadata.CACHE_STRATEGY_PROPERTY)
-                : super.getCacheStrategy();
-    }
-
-    /**
-     * @since 4.0
-     */
-    public String getCacheGroup() {
-        if(overrideExists(QueryMetadata.CACHE_GROUPS_PROPERTY)) {
-            String[] cacheGroups = (String[]) 
overrides.get(QueryMetadata.CACHE_GROUPS_PROPERTY);
-            if(cacheGroups == null || cacheGroups.length == 0) {
-                return null;
-            } else {
-                return cacheGroups[0];
-            }
-        }
-
-        return super.getCacheGroup();
-    }
-
-    public boolean isFetchingDataRows() {
-        if (!overrideExists(QueryMetadata.FETCHING_DATA_ROWS_PROPERTY)) {
-            return super.isFetchingDataRows();
-        }
-
-        Boolean b = (Boolean) 
overrides.get(QueryMetadata.FETCHING_DATA_ROWS_PROPERTY);
-        return b != null && b;
-    }
-
-    public boolean isRefreshingObjects() {
-        return true;
-    }
-
-    public int getPageSize() {
-        if (!overrideExists(QueryMetadata.PAGE_SIZE_PROPERTY)) {
-            return super.getPageSize();
-        }
-
-        Number n = (Number) overrides.get(QueryMetadata.PAGE_SIZE_PROPERTY);
-        return n != null ? n.intValue() : 0;
-    }
-
-    public int getFetchLimit() {
-        if (!overrideExists(QueryMetadata.FETCH_LIMIT_PROPERTY)) {
-            return super.getFetchLimit();
-        }
-
-        Number n = (Number) overrides.get(QueryMetadata.FETCH_LIMIT_PROPERTY);
-        return n != null ? n.intValue() : 0;
-    }
-
-    public int getStatementFetchSize() {
-        if (!overrideExists(QueryMetadata.STATEMENT_FETCH_SIZE_PROPERTY)) {
-            return super.getPageSize();
-        }
-
-        Number n = (Number) 
overrides.get(QueryMetadata.STATEMENT_FETCH_SIZE_PROPERTY);
-        return n != null ? n.intValue() : 0;
-    }
-
-}
diff --git a/cayenne/src/main/java/org/apache/cayenne/query/RefreshQuery.java 
b/cayenne/src/main/java/org/apache/cayenne/query/RefreshQuery.java
index e0227056e..43a9ca0ab 100644
--- a/cayenne/src/main/java/org/apache/cayenne/query/RefreshQuery.java
+++ b/cayenne/src/main/java/org/apache/cayenne/query/RefreshQuery.java
@@ -122,15 +122,18 @@ public class RefreshQuery implements Query {
 
             public QueryMetadata getMetaData(EntityResolver resolver) {
                 QueryMetadata md = query.getMetaData(resolver);
-
-                QueryMetadataWrapper wrappedMd = new QueryMetadataWrapper(md);
-                if (QueryCacheStrategy.LOCAL_CACHE == md.getCacheStrategy()) {
-                    wrappedMd.override(QueryMetadata.CACHE_STRATEGY_PROPERTY, 
QueryCacheStrategy.LOCAL_CACHE_REFRESH);
-                } else if (QueryCacheStrategy.SHARED_CACHE == 
md.getCacheStrategy()) {
-                    wrappedMd.override(QueryMetadata.CACHE_STRATEGY_PROPERTY, 
QueryCacheStrategy.SHARED_CACHE_REFRESH);
-                }
-
-                return wrappedMd;
+                QueryCacheStrategy refreshStrategy = switch 
(md.getCacheStrategy()) {
+                    case LOCAL_CACHE -> QueryCacheStrategy.LOCAL_CACHE_REFRESH;
+                    case SHARED_CACHE -> 
QueryCacheStrategy.SHARED_CACHE_REFRESH;
+                    case null, default -> md.getCacheStrategy();
+                };
+
+                return new QueryMetadataProxy(md) {
+                    @Override
+                    public QueryCacheStrategy getCacheStrategy() {
+                        return refreshStrategy;
+                    }
+                };
             }
 
             public void route(

Reply via email to