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

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

commit 7fcbadb75afc09c555ffdb510917fc175be8d0c3
Author: Andrus Adamchik <[email protected]>
AuthorDate: Sun Jun 28 17:48:32 2026 -0400

    cleanup
---
 .../reader/CryptoRowReaderFactoryDecorator.java    |   9 +-
 .../cayenne/access/jdbc/reader/BaseRowReader.java  |  59 -----------
 .../access/jdbc/reader/CompoundRowReader.java      |  10 +-
 .../jdbc/reader/DefaultRowReaderFactory.java       | 113 ++++++++++++++++-----
 .../access/jdbc/reader/EntityRowReader.java        | 100 ++++++++++--------
 .../cayenne/access/jdbc/reader/FullRowReader.java  |  62 ++++++++---
 .../cayenne/access/jdbc/reader/IdRowReader.java    | 113 ---------------------
 .../{FullRowReader.java => IndexedRowReader.java}  |  42 ++++----
 .../reader/InheritanceAwareEntityRowReader.java    |  47 ---------
 .../jdbc/reader/InheritanceAwareRowReader.java     |  46 ---------
 .../cayenne/access/jdbc/reader/RowReader.java      |   3 +-
 11 files changed, 219 insertions(+), 385 deletions(-)

diff --git 
a/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/reader/CryptoRowReaderFactoryDecorator.java
 
b/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/reader/CryptoRowReaderFactoryDecorator.java
index acfd558fe..61ddd42b3 100644
--- 
a/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/reader/CryptoRowReaderFactoryDecorator.java
+++ 
b/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/reader/CryptoRowReaderFactoryDecorator.java
@@ -18,9 +18,6 @@
  ****************************************************************/
 package org.apache.cayenne.crypto.reader;
 
-import java.sql.ResultSet;
-import java.util.Map;
-
 import org.apache.cayenne.access.jdbc.RSColumn;
 import org.apache.cayenne.access.jdbc.reader.DefaultRowReaderFactory;
 import org.apache.cayenne.access.jdbc.reader.RowReader;
@@ -41,6 +38,9 @@ import org.apache.cayenne.query.EntityResultSegment;
 import org.apache.cayenne.query.QueryMetadata;
 import org.apache.cayenne.query.ScalarResultSegment;
 
+import java.sql.ResultSet;
+import java.util.Map;
+
 public class CryptoRowReaderFactoryDecorator extends DefaultRowReaderFactory {
 
     private TransformerFactory transformerFactory;
@@ -208,8 +208,7 @@ public class CryptoRowReaderFactoryDecorator extends 
DefaultRowReaderFactory {
 
     private class DecoratedFullRowReader extends DecoratedEntityFullRowReader {
 
-        DecoratedFullRowReader(RSColumn[] columns,
-                               RowReader<?> delegateReader) {
+        DecoratedFullRowReader(RSColumn[] columns, RowReader<?> 
delegateReader) {
             super(columns, delegateReader, null);
         }
 
diff --git 
a/cayenne/src/main/java/org/apache/cayenne/access/jdbc/reader/BaseRowReader.java
 
b/cayenne/src/main/java/org/apache/cayenne/access/jdbc/reader/BaseRowReader.java
deleted file mode 100644
index a6cefeab1..000000000
--- 
a/cayenne/src/main/java/org/apache/cayenne/access/jdbc/reader/BaseRowReader.java
+++ /dev/null
@@ -1,59 +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.access.jdbc.reader;
-
-import org.apache.cayenne.access.jdbc.RSColumn;
-import org.apache.cayenne.access.types.ExtendedType;
-import org.apache.cayenne.map.ObjEntity;
-import org.apache.cayenne.query.QueryMetadata;
-
-import java.sql.ResultSet;
-
-/**
- * @since 3.0
- */
-abstract class BaseRowReader<T> implements RowReader<T> {
-
-    ExtendedType[] converters;
-    String[] labels;
-    int[] types;
-    String entityName;
-
-    BaseRowReader(RSColumn[] columns, QueryMetadata queryMetadata) {
-        ObjEntity rootObjEntity = queryMetadata.getObjEntity();
-        if (rootObjEntity != null) {
-            this.entityName = rootObjEntity.getName();
-        }
-
-        int width = columns.length;
-        this.converters = new ExtendedType[width];
-        this.labels = new String[width];
-        this.types = new int[width];
-
-        for (int i = 0; i < width; i++) {
-            converters[i] = columns[i].reader();
-            labels[i] = columns[i].dataRowName();
-            types[i] = columns[i].rsType();
-        }
-    }
-
-    @Override
-    public abstract T readRow(ResultSet resultSet);
-
-}
diff --git 
a/cayenne/src/main/java/org/apache/cayenne/access/jdbc/reader/CompoundRowReader.java
 
b/cayenne/src/main/java/org/apache/cayenne/access/jdbc/reader/CompoundRowReader.java
index 37c195ef7..d0ca470ea 100644
--- 
a/cayenne/src/main/java/org/apache/cayenne/access/jdbc/reader/CompoundRowReader.java
+++ 
b/cayenne/src/main/java/org/apache/cayenne/access/jdbc/reader/CompoundRowReader.java
@@ -27,14 +27,10 @@ import java.sql.ResultSet;
  */
 class CompoundRowReader implements RowReader<Object[]> {
 
-    private RowReader<?>[] readers;
+    private final RowReader<?>[] readers;
 
-    CompoundRowReader(int width) {
-        this.readers = new RowReader[width];
-    }
-
-    void addRowReader(int pos, RowReader<?> reader) {
-        this.readers[pos] = reader;
+    public CompoundRowReader(RowReader<?>[] readers) {
+        this.readers = readers;
     }
 
     @Override
diff --git 
a/cayenne/src/main/java/org/apache/cayenne/access/jdbc/reader/DefaultRowReaderFactory.java
 
b/cayenne/src/main/java/org/apache/cayenne/access/jdbc/reader/DefaultRowReaderFactory.java
index 84fdda10d..0952a3d6f 100644
--- 
a/cayenne/src/main/java/org/apache/cayenne/access/jdbc/reader/DefaultRowReaderFactory.java
+++ 
b/cayenne/src/main/java/org/apache/cayenne/access/jdbc/reader/DefaultRowReaderFactory.java
@@ -22,6 +22,9 @@ import org.apache.cayenne.CayenneRuntimeException;
 import org.apache.cayenne.access.jdbc.RSColumn;
 import org.apache.cayenne.access.types.ExtendedType;
 import org.apache.cayenne.dba.DbAdapter;
+import org.apache.cayenne.map.DbAttribute;
+import org.apache.cayenne.map.DbEntity;
+import org.apache.cayenne.map.ObjEntity;
 import org.apache.cayenne.query.EmbeddableResultSegment;
 import org.apache.cayenne.query.EntityResultSegment;
 import org.apache.cayenne.query.QueryMetadata;
@@ -37,26 +40,22 @@ public class DefaultRowReaderFactory implements 
RowReaderFactory {
     @Override
     public RowReader<?> rowReader(RSColumn[] columns, QueryMetadata 
queryMetadata, DbAdapter adapter) {
 
-        List<Object> rsMapping = queryMetadata.getResultSetMapping();
-        if (rsMapping == null) {
+        List<Object> segments = queryMetadata.getResultSetMapping();
+        if (segments == null || segments.isEmpty()) {
             return createFullRowReader(columns, queryMetadata);
         }
 
-        int resultWidth = rsMapping.size();
-        if (resultWidth == 0) {
-            throw new CayenneRuntimeException("Empty result columns");
-        }
-
         if (queryMetadata.isSingleResultSetMapping()) {
-            return segmentRowReader(rsMapping.getFirst(), columns, 
queryMetadata);
-        } else {
-            CompoundRowReader reader = new CompoundRowReader(resultWidth);
-            for (int i = 0; i < resultWidth; i++) {
-                reader.addRowReader(i, segmentRowReader(rsMapping.get(i), 
columns, queryMetadata));
-            }
+            return segmentRowReader(segments.getFirst(), columns, 
queryMetadata);
+        }
 
-            return reader;
+        int w = segments.size();
+        RowReader<?>[] readers = new RowReader[w];
+        for (int i = 0; i < w; i++) {
+            readers[i] = segmentRowReader(segments.get(i), columns, 
queryMetadata);
         }
+
+        return new CompoundRowReader(readers);
     }
 
     private RowReader<?> segmentRowReader(Object segment, RSColumn[] columns, 
QueryMetadata queryMetadata) {
@@ -93,27 +92,89 @@ public class DefaultRowReaderFactory implements 
RowReaderFactory {
                 columns[scalarIndex].rsType());
     }
 
-    protected RowReader<?> createEntityRowReader(RSColumn[] columns, 
QueryMetadata queryMetadata,
-                                                 EntityResultSegment 
resultMetadata) {
+    protected RowReader<?> createEntityRowReader(
+            RSColumn[] columns,
+            QueryMetadata queryMetadata,
+            EntityResultSegment resultMetadata) {
 
         if (queryMetadata.getPageSize() > 0) {
-            return new IdRowReader<>(columns, queryMetadata, resultMetadata);
-        } else if (resultMetadata.getClassDescriptor() != null && 
resultMetadata.getClassDescriptor().hasSubclasses()) {
-            return new InheritanceAwareEntityRowReader(columns, 
resultMetadata);
-        } else {
-            return new EntityRowReader(columns, resultMetadata);
+            return createIdRowReader(columns, queryMetadata, resultMetadata);
         }
+
+        int startIndex = resultMetadata.getColumnOffset();
+        int segmentWidth = resultMetadata.getFields().size();
+        ExtendedType<?>[] readers = new ExtendedType[segmentWidth];
+        int[] types = new int[segmentWidth];
+        String[] labels = new String[segmentWidth];
+
+        for (int i = 0; i < segmentWidth; i++) {
+            RSColumn column = columns[startIndex + i];
+            readers[i] = column.reader();
+            types[i] = column.rsType();
+
+            // the query translator may reorder fields compared to the entity 
result, so resolve the
+            // DataRow label by reverse lookup of the column name...
+            if (column.dataRowName().contains(".")) {
+                // a dotted dataRowName is a prefetched column - use it 
directly instead of by alias
+                labels[i] = column.dataRowName();
+            } else {
+                labels[i] = resultMetadata.getColumnPath(column.dataRowName());
+            }
+        }
+
+        return EntityRowReader.of(readers, types, labels, startIndex, 
resultMetadata.getClassDescriptor());
     }
 
     protected RowReader<?> createFullRowReader(RSColumn[] columns, 
QueryMetadata queryMetadata) {
 
         if (queryMetadata.getPageSize() > 0) {
-            return new IdRowReader<>(columns, queryMetadata, null);
-        } else if (queryMetadata.getClassDescriptor() != null && 
queryMetadata.getClassDescriptor().hasSubclasses()) {
-            return new InheritanceAwareRowReader(columns, queryMetadata);
-        } else {
-            return new FullRowReader(columns, queryMetadata);
+            return createIdRowReader(columns, queryMetadata, null);
+        }
+
+        return FullRowReader.of(columns, queryMetadata);
+    }
+
+    private RowReader<?> createIdRowReader(RSColumn[] columns, QueryMetadata 
queryMetadata,
+                                           EntityResultSegment resultMetadata) 
{
+        int[] pk = pkIndices(columns, queryMetadata, resultMetadata);
+
+        // single-column PK - read the value directly as a scalar
+        if (pk.length == 1) {
+            RSColumn column = columns[pk[0]];
+            // jdbc column indexes start from 1
+            return new ScalarRowReader<>(column.reader(), pk[0] + 1, 
column.rsType());
+        }
+
+        return new IndexedRowReader(columns, entityName(queryMetadata), pk);
+    }
+
+    private static String entityName(QueryMetadata queryMetadata) {
+        ObjEntity objEntity = queryMetadata.getObjEntity();
+        return objEntity != null ? objEntity.getName() : null;
+    }
+
+    private static int[] pkIndices(RSColumn[] columns, QueryMetadata 
queryMetadata, EntityResultSegment resultMetadata) {
+        DbEntity dbEntity = resultMetadata == null
+                ? queryMetadata.getDbEntity()
+                : 
resultMetadata.getClassDescriptor().getEntity().getDbEntity();
+        if (dbEntity == null) {
+            throw new CayenneRuntimeException("Null root DbEntity, can't index 
PK");
+        }
+
+        int len = dbEntity.getPrimaryKeys().size();
+        if (len == 0) {
+            throw new CayenneRuntimeException("Root DBEntity has no PK 
defined: %s", dbEntity);
+        }
+
+        int[] pk = new int[len];
+        int offset = resultMetadata != null ? resultMetadata.getColumnOffset() 
: 0;
+        for (int i = offset, j = 0; i < offset + len; i++) {
+            DbAttribute a = dbEntity.getAttribute(columns[i].rsName());
+            if (a != null && a.isPrimaryKey()) {
+                pk[j++] = i;
+            }
         }
+        return pk;
     }
 
 }
diff --git 
a/cayenne/src/main/java/org/apache/cayenne/access/jdbc/reader/EntityRowReader.java
 
b/cayenne/src/main/java/org/apache/cayenne/access/jdbc/reader/EntityRowReader.java
index 524066fa1..eb4413829 100644
--- 
a/cayenne/src/main/java/org/apache/cayenne/access/jdbc/reader/EntityRowReader.java
+++ 
b/cayenne/src/main/java/org/apache/cayenne/access/jdbc/reader/EntityRowReader.java
@@ -18,59 +18,48 @@
  ****************************************************************/
 package org.apache.cayenne.access.jdbc.reader;
 
-import java.sql.ResultSet;
-
 import org.apache.cayenne.CayenneRuntimeException;
 import org.apache.cayenne.DataRow;
-import org.apache.cayenne.access.jdbc.RSColumn;
 import org.apache.cayenne.access.types.ExtendedType;
-import org.apache.cayenne.query.EntityResultSegment;
+import org.apache.cayenne.map.EntityInheritanceTree;
+import org.apache.cayenne.map.ObjEntity;
 import org.apache.cayenne.reflect.ClassDescriptor;
 import org.apache.cayenne.util.Util;
 
+import java.sql.ResultSet;
+
 /**
  * @since 3.0
  */
 class EntityRowReader implements RowReader<DataRow> {
 
-    private ExtendedType[] converters;
-    private String[] labels;
-    private int[] types;
-
-    String entityName;
-    private int mapCapacity;
-    private int startIndex;
-
-    EntityRowReader(RSColumn[] columns, EntityResultSegment segmentMetadata) {
-
-        ClassDescriptor classDescriptor = segmentMetadata.getClassDescriptor();
-
-        if (classDescriptor != null) {
-            this.entityName = classDescriptor.getEntity().getName();
-        }
+    private final ExtendedType<?>[] readers;
+    private final String[] labels;
+    private final int[] types;
+    private final int mapCapacity;
+    private final int startIndex;
+    protected final String entityName;
+
+    static RowReader<DataRow> of(
+            ExtendedType<?>[] readers,
+            int[] types,
+            String[] labels,
+            int startIndex,
+            ClassDescriptor classDescriptor) {
+
+        String entityName = classDescriptor != null ? 
classDescriptor.getEntity().getName() : null;
+        return classDescriptor != null && classDescriptor.hasSubclasses()
+                ? new InheritanceAwareEntityRowReader(readers, types, labels, 
startIndex, entityName, classDescriptor.getEntityInheritanceTree())
+                : new EntityRowReader(readers, types, labels, startIndex, 
entityName);
+    }
 
-        int segmentWidth = segmentMetadata.getFields().size();
-        this.startIndex = segmentMetadata.getColumnOffset();
-        this.converters = new ExtendedType[segmentWidth];
-        this.types = new int[segmentWidth];
-        this.labels = new String[segmentWidth];
-
-        for (int i = 0; i < segmentWidth; i++) {
-            this.converters[i] = columns[startIndex + i].reader();
-            types[i] = columns[startIndex + i].rsType();
-
-            // query translator may change the order of fields compare to the 
entity
-            // result, so figure out DataRow labels by doing reverse lookup of
-            // RowDescriptor labels...
-            if (columns[startIndex + i].dataRowName().contains(".")) {
-                // if the dataRowKey contains ".", it is prefetched column and
-                // we can use it instead of search the name by alias
-                labels[i] = columns[startIndex + i].dataRowName();
-            } else {
-                labels[i] = segmentMetadata.getColumnPath(columns[startIndex + 
i].dataRowName());
-            }
-        }
-        this.mapCapacity = (int) Math.ceil(segmentWidth / 0.75);
+    protected EntityRowReader(ExtendedType<?>[] readers, int[] types, String[] 
labels, int startIndex, String entityName) {
+        this.readers = readers;
+        this.types = types;
+        this.labels = labels;
+        this.startIndex = startIndex;
+        this.entityName = entityName;
+        this.mapCapacity = (int) Math.ceil(readers.length / 0.75);
     }
 
     @Override
@@ -78,12 +67,12 @@ class EntityRowReader implements RowReader<DataRow> {
 
         try {
             DataRow row = new DataRow(mapCapacity);
-            int len = converters.length;
+            int len = readers.length;
 
             for (int i = 0; i < len; i++) {
 
                 // note: jdbc column indexes start from 1, not 0 as in arrays
-                Object val = converters[i].materializeObject(resultSet, 
startIndex + i + 1, types[i]);
+                Object val = readers[i].materializeObject(resultSet, 
startIndex + i + 1, types[i]);
                 row.put(labels[i], val);
             }
 
@@ -98,7 +87,30 @@ class EntityRowReader implements RowReader<DataRow> {
         }
     }
 
-    void postprocessRow(ResultSet resultSet, DataRow dataRow) throws Exception 
{
+    protected void postprocessRow(ResultSet resultSet, DataRow dataRow) {
         dataRow.setEntityName(entityName);
     }
+
+    private static class InheritanceAwareEntityRowReader extends 
EntityRowReader {
+
+        private final EntityInheritanceTree entityInheritanceTree;
+
+        InheritanceAwareEntityRowReader(
+                ExtendedType<?>[] readers,
+                int[] types,
+                String[] labels,
+                int startIndex,
+                String entityName,
+                EntityInheritanceTree entityInheritanceTree) {
+
+            super(readers, types, labels, startIndex, entityName);
+            this.entityInheritanceTree = entityInheritanceTree;
+        }
+
+        @Override
+        protected void postprocessRow(ResultSet resultSet, DataRow dataRow) {
+            ObjEntity entity = 
entityInheritanceTree.entityMatchingRow(dataRow);
+            dataRow.setEntityName(entity != null ? entity.getName() : 
entityName);
+        }
+    }
 }
diff --git 
a/cayenne/src/main/java/org/apache/cayenne/access/jdbc/reader/FullRowReader.java
 
b/cayenne/src/main/java/org/apache/cayenne/access/jdbc/reader/FullRowReader.java
index 31857d6cd..84bd20284 100644
--- 
a/cayenne/src/main/java/org/apache/cayenne/access/jdbc/reader/FullRowReader.java
+++ 
b/cayenne/src/main/java/org/apache/cayenne/access/jdbc/reader/FullRowReader.java
@@ -21,35 +21,53 @@ package org.apache.cayenne.access.jdbc.reader;
 import org.apache.cayenne.CayenneRuntimeException;
 import org.apache.cayenne.DataRow;
 import org.apache.cayenne.access.jdbc.RSColumn;
+import org.apache.cayenne.map.EntityInheritanceTree;
+import org.apache.cayenne.map.ObjEntity;
 import org.apache.cayenne.query.QueryMetadata;
+import org.apache.cayenne.reflect.ClassDescriptor;
 
 import java.sql.ResultSet;
 
 /**
  * @since 3.0
  */
-class FullRowReader extends BaseRowReader<DataRow> {
+class FullRowReader implements RowReader<DataRow> {
 
-    int mapCapacity;
+    private final RSColumn[] columns;
+    private final int mapCapacity;
+    protected final String entityName;
 
-    FullRowReader(RSColumn[] columns, QueryMetadata queryMetadata) {
-        super(columns, queryMetadata);
+    static RowReader<DataRow> of(RSColumn[] columns, QueryMetadata 
queryMetadata) {
+
+        ObjEntity objEntity = queryMetadata.getObjEntity();
+        String entityName = objEntity != null ? objEntity.getName() : null;
+
+        ClassDescriptor classDescriptor = queryMetadata.getClassDescriptor();
+        if (classDescriptor != null && classDescriptor.hasSubclasses()) {
+            return new InheritanceAwareRowReader(columns, entityName, 
classDescriptor.getEntityInheritanceTree());
+        }
+
+        return new FullRowReader(columns, entityName);
+    }
+
+    public FullRowReader(RSColumn[] columns, String entityName) {
+        this.columns = columns;
+        this.entityName = entityName;
         this.mapCapacity = (int) Math.ceil(columns.length / 0.75);
     }
 
     @Override
     public DataRow readRow(ResultSet resultSet) {
-        try {
-            DataRow dataRow = new DataRow(mapCapacity);
+        DataRow dataRow = new DataRow(mapCapacity);
+        int w = columns.length;
 
-            int resultWidth = labels.length;
+        try {
 
-            // process result row columns,
-            for (int i = 0; i < resultWidth; i++) {
-                // note: jdbc column indexes start from 1, not 0 unlike
-                // everywhere else
-                Object val = converters[i].materializeObject(resultSet, i + 1, 
types[i]);
-                dataRow.put(labels[i], val);
+            for (int i = 0; i < w; i++) {
+                RSColumn column = columns[i];
+                // jdbc column indexes start from 1, not 0 unlike everywhere 
else
+                Object val = column.reader().materializeObject(resultSet, i + 
1, column.rsType());
+                dataRow.put(column.dataRowName(), val);
             }
 
             postprocessRow(resultSet, dataRow);
@@ -62,7 +80,23 @@ class FullRowReader extends BaseRowReader<DataRow> {
         }
     }
 
-    void postprocessRow(ResultSet resultSet, DataRow dataRow) throws Exception 
{
+    protected void postprocessRow(ResultSet resultSet, DataRow dataRow) {
         dataRow.setEntityName(entityName);
     }
+
+    private static class InheritanceAwareRowReader extends FullRowReader {
+
+        private final EntityInheritanceTree entityInheritanceTree;
+
+        InheritanceAwareRowReader(RSColumn[] columns, String entityName, 
EntityInheritanceTree entityInheritanceTree) {
+            super(columns, entityName);
+            this.entityInheritanceTree = entityInheritanceTree;
+        }
+
+        @Override
+        protected void postprocessRow(ResultSet resultSet, DataRow dataRow) {
+            ObjEntity entity = 
entityInheritanceTree.entityMatchingRow(dataRow);
+            dataRow.setEntityName(entity != null ? entity.getName() : 
entityName);
+        }
+    }
 }
diff --git 
a/cayenne/src/main/java/org/apache/cayenne/access/jdbc/reader/IdRowReader.java 
b/cayenne/src/main/java/org/apache/cayenne/access/jdbc/reader/IdRowReader.java
deleted file mode 100644
index 789ccf2d8..000000000
--- 
a/cayenne/src/main/java/org/apache/cayenne/access/jdbc/reader/IdRowReader.java
+++ /dev/null
@@ -1,113 +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.access.jdbc.reader;
-
-import org.apache.cayenne.CayenneRuntimeException;
-import org.apache.cayenne.DataRow;
-import org.apache.cayenne.access.jdbc.RSColumn;
-import org.apache.cayenne.map.DbAttribute;
-import org.apache.cayenne.map.DbEntity;
-import org.apache.cayenne.query.EntityResultSegment;
-import org.apache.cayenne.query.QueryMetadata;
-import org.apache.cayenne.util.Util;
-
-import java.sql.ResultSet;
-
-/**
- * @since 3.0
- */
-class IdRowReader<T> extends BaseRowReader<T> {
-
-    protected int[] pkIndices;
-
-    public IdRowReader(RSColumn[] columns, QueryMetadata queryMetadata, 
EntityResultSegment resultMetadata) {
-        super(columns, queryMetadata);
-
-        DbEntity dbEntity = resultMetadata == null
-                ? queryMetadata.getDbEntity()
-                : 
resultMetadata.getClassDescriptor().getEntity().getDbEntity();
-        if (dbEntity == null) {
-            throw new CayenneRuntimeException("Null root DbEntity, can't index 
PK");
-        }
-
-        int len = dbEntity.getPrimaryKeys().size();
-
-        // sanity check
-        if (len == 0) {
-            throw new CayenneRuntimeException("Root DBEntity has no PK 
defined: %s", dbEntity);
-        }
-
-        int[] pk = new int[len];
-        int offset = resultMetadata != null ?
-                resultMetadata.getColumnOffset() :
-                0;
-        for(int i = offset, j = 0; i < offset + len; i++) {
-            DbAttribute a = dbEntity.getAttribute(columns[i].rsName());
-            if(a != null && a.isPrimaryKey()) {
-                pk[j++] = i;
-            }
-        }
-
-        this.pkIndices = pk;
-    }
-
-    @Override
-    public T readRow(ResultSet resultSet) {
-        try {
-            if (pkIndices.length == 1) {
-                return readSingleId(resultSet);
-            } else {
-                return readIdMap(resultSet);
-            }
-        } catch (CayenneRuntimeException cex) {
-            // rethrow unmodified
-            throw cex;
-        } catch (Exception otherex) {
-            throw new CayenneRuntimeException("Exception materializing id 
column.", Util.unwindException(otherex));
-        }
-    }
-
-    private T readSingleId(ResultSet resultSet) throws Exception {
-
-        // dereference column index
-        int index = pkIndices[0];
-
-        // note: jdbc column indexes start from 1, not 0 as in arrays
-        @SuppressWarnings("unchecked")
-        T val = (T) converters[index].materializeObject(resultSet, index + 1, 
types[index]);
-
-        return val;
-    }
-
-    @SuppressWarnings("unchecked")
-    private T readIdMap(ResultSet resultSet) throws Exception {
-
-        DataRow idRow = new DataRow(2);
-        idRow.setEntityName(entityName);
-
-        for (int index : pkIndices) {
-            // dereference column index
-            // note: jdbc column indexes start from 1, not 0 as in arrays
-            Object val = converters[index].materializeObject(resultSet, index 
+ 1, types[index]);
-            idRow.put(labels[index], val);
-        }
-
-        return (T) idRow;
-    }
-}
diff --git 
a/cayenne/src/main/java/org/apache/cayenne/access/jdbc/reader/FullRowReader.java
 
b/cayenne/src/main/java/org/apache/cayenne/access/jdbc/reader/IndexedRowReader.java
similarity index 60%
copy from 
cayenne/src/main/java/org/apache/cayenne/access/jdbc/reader/FullRowReader.java
copy to 
cayenne/src/main/java/org/apache/cayenne/access/jdbc/reader/IndexedRowReader.java
index 31857d6cd..605b99790 100644
--- 
a/cayenne/src/main/java/org/apache/cayenne/access/jdbc/reader/FullRowReader.java
+++ 
b/cayenne/src/main/java/org/apache/cayenne/access/jdbc/reader/IndexedRowReader.java
@@ -21,48 +21,46 @@ package org.apache.cayenne.access.jdbc.reader;
 import org.apache.cayenne.CayenneRuntimeException;
 import org.apache.cayenne.DataRow;
 import org.apache.cayenne.access.jdbc.RSColumn;
-import org.apache.cayenne.query.QueryMetadata;
 
 import java.sql.ResultSet;
 
 /**
- * @since 3.0
+ * A {@link RowReader} that materializes a subset of the result columns.
  */
-class FullRowReader extends BaseRowReader<DataRow> {
+class IndexedRowReader implements RowReader<DataRow> {
 
-    int mapCapacity;
+    private final String entityName;
+    private final RSColumn[] columns;
+    private final int[] indices;
+    private final int mapCapacity;
 
-    FullRowReader(RSColumn[] columns, QueryMetadata queryMetadata) {
-        super(columns, queryMetadata);
-        this.mapCapacity = (int) Math.ceil(columns.length / 0.75);
+    public IndexedRowReader(RSColumn[] columns, String entityName, int[] 
indices) {
+        this.columns = columns;
+        this.entityName = entityName;
+        this.mapCapacity = (int) Math.ceil(indices.length / 0.75);
+        this.indices = indices;
     }
 
     @Override
     public DataRow readRow(ResultSet resultSet) {
-        try {
-            DataRow dataRow = new DataRow(mapCapacity);
+        DataRow dataRow = new DataRow(mapCapacity);
 
-            int resultWidth = labels.length;
+        try {
 
-            // process result row columns,
-            for (int i = 0; i < resultWidth; i++) {
-                // note: jdbc column indexes start from 1, not 0 unlike
-                // everywhere else
-                Object val = converters[i].materializeObject(resultSet, i + 1, 
types[i]);
-                dataRow.put(labels[i], val);
+            for (int index : indices) {
+                RSColumn column = columns[index];
+                // jdbc column indexes start from 1, not 0 unlike everywhere 
else
+                Object val = column.reader().materializeObject(resultSet, 
index + 1, column.rsType());
+                dataRow.put(column.dataRowName(), val);
             }
 
-            postprocessRow(resultSet, dataRow);
+            dataRow.setEntityName(entityName);
 
             return dataRow;
         } catch (CayenneRuntimeException ex) {
             throw ex;
         } catch (Exception ex) {
-            throw new CayenneRuntimeException("Exception materializing 
column.", ex);
+            throw new CayenneRuntimeException("Exception materializing id 
column.", ex);
         }
     }
-
-    void postprocessRow(ResultSet resultSet, DataRow dataRow) throws Exception 
{
-        dataRow.setEntityName(entityName);
-    }
 }
diff --git 
a/cayenne/src/main/java/org/apache/cayenne/access/jdbc/reader/InheritanceAwareEntityRowReader.java
 
b/cayenne/src/main/java/org/apache/cayenne/access/jdbc/reader/InheritanceAwareEntityRowReader.java
deleted file mode 100644
index 449b7ebeb..000000000
--- 
a/cayenne/src/main/java/org/apache/cayenne/access/jdbc/reader/InheritanceAwareEntityRowReader.java
+++ /dev/null
@@ -1,47 +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.access.jdbc.reader;
-
-import java.sql.ResultSet;
-
-import org.apache.cayenne.DataRow;
-import org.apache.cayenne.access.jdbc.RSColumn;
-import org.apache.cayenne.map.EntityInheritanceTree;
-import org.apache.cayenne.map.ObjEntity;
-import org.apache.cayenne.query.EntityResultSegment;
-
-/**
- * @since 3.0
- */
-class InheritanceAwareEntityRowReader extends EntityRowReader {
-
-    private EntityInheritanceTree entityInheritanceTree;
-
-    public InheritanceAwareEntityRowReader(RSColumn[] columns, 
EntityResultSegment segmentMetadata) {
-
-        super(columns, segmentMetadata);
-        this.entityInheritanceTree = 
segmentMetadata.getClassDescriptor().getEntityInheritanceTree();
-    }
-
-    @Override
-    void postprocessRow(ResultSet resultSet, DataRow dataRow) throws Exception 
{
-        ObjEntity entity = entityInheritanceTree.entityMatchingRow(dataRow);
-        dataRow.setEntityName(entity != null ? entity.getName() : entityName);
-    }
-}
diff --git 
a/cayenne/src/main/java/org/apache/cayenne/access/jdbc/reader/InheritanceAwareRowReader.java
 
b/cayenne/src/main/java/org/apache/cayenne/access/jdbc/reader/InheritanceAwareRowReader.java
deleted file mode 100644
index 7d765089f..000000000
--- 
a/cayenne/src/main/java/org/apache/cayenne/access/jdbc/reader/InheritanceAwareRowReader.java
+++ /dev/null
@@ -1,46 +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.access.jdbc.reader;
-
-import java.sql.ResultSet;
-
-import org.apache.cayenne.DataRow;
-import org.apache.cayenne.access.jdbc.RSColumn;
-import org.apache.cayenne.map.EntityInheritanceTree;
-import org.apache.cayenne.map.ObjEntity;
-import org.apache.cayenne.query.QueryMetadata;
-
-/**
- * @since 3.0
- */
-class InheritanceAwareRowReader extends FullRowReader {
-
-    private EntityInheritanceTree entityInheritanceTree;
-
-    InheritanceAwareRowReader(RSColumn[] columns, QueryMetadata queryMetadata) 
{
-        super(columns, queryMetadata);
-        this.entityInheritanceTree = 
queryMetadata.getClassDescriptor().getEntityInheritanceTree();
-    }
-
-    @Override
-    void postprocessRow(ResultSet resultSet, DataRow dataRow) throws Exception 
{
-        ObjEntity entity = entityInheritanceTree.entityMatchingRow(dataRow);
-        dataRow.setEntityName(entity != null ? entity.getName() : entityName);
-    }
-}
diff --git 
a/cayenne/src/main/java/org/apache/cayenne/access/jdbc/reader/RowReader.java 
b/cayenne/src/main/java/org/apache/cayenne/access/jdbc/reader/RowReader.java
index 4a1599a94..1bb55ec91 100644
--- a/cayenne/src/main/java/org/apache/cayenne/access/jdbc/reader/RowReader.java
+++ b/cayenne/src/main/java/org/apache/cayenne/access/jdbc/reader/RowReader.java
@@ -21,8 +21,7 @@ package org.apache.cayenne.access.jdbc.reader;
 import java.sql.ResultSet;
 
 /**
- * A strategy class that encapsulates an algorithm for converting a single
- * ResultSet row into a DataRow.
+ * A strategy class that encapsulates an algorithm for converting a single 
ResultSet row into a DataRow.
  * 
  * @since 3.0
  */


Reply via email to