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 da205371d57d3259a1399b4354cc8ac1c038d6ba
Author: Andrus Adamchik <[email protected]>
AuthorDate: Sun Aug 30 16:57:40 2026 -0400

    CAY-3007 Deprecate SelectById
---
 RELEASE-NOTES.txt                                  |   1 +
 .../cayenne/commitlog/DeletedDiffProcessor.java    |   1 -
 .../org/apache/cayenne/exp/parser/ASTDbPath.java   |   7 +-
 .../cayenne/exp/property/EntityProperty.java       |  98 ++++++
 .../java/org/apache/cayenne/map/ObjEntity.java     |  11 +
 .../java/org/apache/cayenne/query/SelectById.java  |  27 ++
 .../org/apache/cayenne/CDOMapRelationshipIT.java   |   5 +-
 .../org/apache/cayenne/CDOSetRelationshipIT.java   |   5 +-
 .../java/org/apache/cayenne/MeaningfulFKIT.java    |   5 +-
 .../access/DataContextFlattenedAttributesIT.java   |   7 +-
 .../apache/cayenne/access/EntityInheritanceIT.java |   5 +-
 .../cayenne/access/VerticalInheritanceIT.java      |  39 +--
 .../translator/select/QualifierTranslatorIT.java   |   4 -
 .../cayenne/commitlog/CommitLogFilterIT.java       |  36 ++-
 .../commitlog/CommitLogFilter_All_FlattenedIT.java |   8 +-
 .../commitlog/CommitLogFilter_FilteredIT.java      |  29 +-
 .../CommitLogFilter_ListenerInducedChangesIT.java  |   8 +-
 .../cayenne/exp/property/EntityPropertyIdIT.java   | 161 ++++++++++
 .../apache/cayenne/query/ObjectSelect_ByIdIT.java  | 356 +++++++++++++++++++++
 .../cayenne/query/SelectByIdIteratedQueryIT.java   |   1 +
 .../org/apache/cayenne/query/SelectByIdTest.java   |   1 +
 .../org/apache/cayenne/query/SelectById_RunIT.java |   1 +
 .../org/apache/cayenne/value/json/JsonTypeIT.java  |   8 +-
 23 files changed, 750 insertions(+), 74 deletions(-)

diff --git a/RELEASE-NOTES.txt b/RELEASE-NOTES.txt
index d383ab82c..1c473c4f6 100644
--- a/RELEASE-NOTES.txt
+++ b/RELEASE-NOTES.txt
@@ -16,6 +16,7 @@ Changes/New Features:
 CAY-2998 Modeler: clickabe "Target" column to navigate relationships
 CAY-3000 Modeler: unifying the main views of all model objects
 CAY-3004 Modeler: Rework DbEntity PK generation UI to match the XML model
+CAY-3007 Deprecate SelectById
 
 Bug Fixes:
 
diff --git 
a/cayenne/src/main/java/org/apache/cayenne/commitlog/DeletedDiffProcessor.java 
b/cayenne/src/main/java/org/apache/cayenne/commitlog/DeletedDiffProcessor.java
index edd5f329b..4ffa7ddcb 100644
--- 
a/cayenne/src/main/java/org/apache/cayenne/commitlog/DeletedDiffProcessor.java
+++ 
b/cayenne/src/main/java/org/apache/cayenne/commitlog/DeletedDiffProcessor.java
@@ -56,7 +56,6 @@ class DeletedDiffProcessor implements GraphChangeHandler {
 
                final MutableObjectChange objectChangeSet = 
changeSet.getOrCreate(id, ObjectChangeType.DELETE);
 
-               // TODO: rewrite with SelectById query after Cayenne upgrade
                ObjectIdQuery query = new ObjectIdQuery(id, true, 
ObjectIdQuery.CACHE);
                QueryResponse result = channel.onQuery(null, query);
 
diff --git a/cayenne/src/main/java/org/apache/cayenne/exp/parser/ASTDbPath.java 
b/cayenne/src/main/java/org/apache/cayenne/exp/parser/ASTDbPath.java
index 553314621..c397648e5 100644
--- a/cayenne/src/main/java/org/apache/cayenne/exp/parser/ASTDbPath.java
+++ b/cayenne/src/main/java/org/apache/cayenne/exp/parser/ASTDbPath.java
@@ -30,6 +30,7 @@ import org.apache.cayenne.ObjectContext;
 import org.apache.cayenne.ObjectId;
 import org.apache.cayenne.Persistent;
 import org.apache.cayenne.access.DataContext;
+import org.apache.cayenne.DataRow;
 import org.apache.cayenne.exp.Expression;
 import org.apache.cayenne.exp.ExpressionFactory;
 import org.apache.cayenne.exp.path.CayennePath;
@@ -38,7 +39,6 @@ import org.apache.cayenne.map.DbRelationship;
 import org.apache.cayenne.map.Entity;
 import org.apache.cayenne.map.ObjEntity;
 import org.apache.cayenne.query.ObjectSelect;
-import org.apache.cayenne.query.SelectById;
 import org.apache.cayenne.util.CayenneMapEntry;
 
 /**
@@ -149,7 +149,10 @@ public class ASTDbPath extends ASTPath {
                }
 
                if (oid != null) {
-                       return 
SelectById.dataRowQuery(persistent.getObjectId()).selectOne(context);
+                       return ObjectSelect.query(DataRow.class, 
oid.getEntityName())
+                                       .fetchDataRows()
+                                       
.where(ExpressionFactory.matchExp(ExpressionFactory.fullObjectExp(), oid))
+                                       .selectOne(context);
                }
 
                // fallback to ID snapshot as a last resort
diff --git 
a/cayenne/src/main/java/org/apache/cayenne/exp/property/EntityProperty.java 
b/cayenne/src/main/java/org/apache/cayenne/exp/property/EntityProperty.java
index 59dba8ca2..8465d84a8 100644
--- a/cayenne/src/main/java/org/apache/cayenne/exp/property/EntityProperty.java
+++ b/cayenne/src/main/java/org/apache/cayenne/exp/property/EntityProperty.java
@@ -19,8 +19,14 @@
 
 package org.apache.cayenne.exp.property;
 
+import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collection;
+import java.util.List;
+import java.util.Map;
 
+import org.apache.cayenne.CayenneRuntimeException;
+import org.apache.cayenne.ObjectId;
 import org.apache.cayenne.Persistent;
 import org.apache.cayenne.exp.Expression;
 import org.apache.cayenne.exp.ExpressionFactory;
@@ -143,6 +149,98 @@ public class EntityProperty<E extends Persistent> extends 
BaseProperty<E> implem
         return ExpressionFactory.notInExp(getExpression(), ids);
     }
 
+
+    /**
+     * Matches an object by a possibly compound id, expressed as a map of DB 
attribute names to values.
+     * Unlike {@link #eqId(Object)} this form supports entities with a 
compound PK.
+     *
+     * @param id a map of the target entity PK attribute names to values
+     * @return an expression matching an object with the given id
+     * @since 5.0
+     */
+    public Expression eqIdMap(Map<String, ?> id) {
+        return idExp(id);
+    }
+
+    /**
+     * @param id a map of the target entity PK attribute names to values
+     * @return an expression excluding an object with the given id
+     * @since 5.0
+     * @see #eqIdMap(Map)
+     */
+    public Expression neqIdMap(Map<String, ?> id) {
+        return idExp(id).notExp();
+    }
+
+    /**
+     * Matches any of the objects identified by the provided ids. Unlike 
{@link #idsIn(Object...)} this form
+     * supports entities with a compound PK, expanding to an {@code OR} of 
per-id matches rather than an
+     * {@code IN}, as SQL {@code IN} can't be applied to a multi-column key.
+     *
+     * @param ids maps of the target entity PK attribute names to values
+     * @since 5.0
+     * @see #eqIdMap(Map)
+     */
+    @SafeVarargs
+    public final Expression idMapsIn(Map<String, ?>... ids) {
+        return idMapsInCollection(Arrays.asList(ids));
+    }
+
+    /**
+     * @param ids maps of the target entity PK attribute names to values
+     * @since 5.0
+     * @see #idMapsIn(Map[])
+     */
+    public Expression idMapsInCollection(Collection<Map<String, ?>> ids) {
+        List<Expression> expressions = new ArrayList<>(ids.size());
+        for (Map<String, ?> id : ids) {
+            expressions.add(idExp(id));
+        }
+        return expressions.isEmpty() ? ExpressionFactory.expFalse() : 
ExpressionFactory.joinExp(Expression.OR, expressions);
+    }
+
+    /**
+     * Matches any of the objects identified by the provided {@link 
ObjectId}s. Unlike
+     * {@link #idsIn(Object...)} this form supports entities with a compound 
PK.
+     *
+     * @since 5.0
+     * @see #idMapsIn(Map[])
+     */
+    public Expression objectIdsIn(ObjectId... ids) {
+        return objectIdsInCollection(Arrays.asList(ids));
+    }
+
+    /**
+     * @since 5.0
+     * @see #objectIdsIn(ObjectId...)
+     */
+    public Expression objectIdsInCollection(Collection<ObjectId> ids) {
+        List<Map<String, ?>> snapshots = new ArrayList<>(ids.size());
+        for (ObjectId id : ids) {
+            snapshots.add(id.getIdSnapshot());
+        }
+        return idMapsInCollection(snapshots);
+    }
+
+    /**
+     * Builds an {@code AND} of per-PK-attribute matches. Paths are built as 
"dbid:" paths relative to this
+     * property, so they resolve through the Obj layer and work for both the 
query root (an empty path, see
+     * {@link SelfProperty}) and a to-one relationship.
+     */
+    private Expression idExp(Map<String, ?> id) {
+        if (id == null || id.isEmpty()) {
+            throw new CayenneRuntimeException("Null or empty id map");
+        }
+
+        Expression result = null;
+        for (Map.Entry<String, ?> entry : id.entrySet()) {
+            Expression next = ExpressionFactory
+                    
.matchExp(ExpressionFactory.dbIdPathExp(getPath().dot(entry.getKey())), 
entry.getValue());
+            result = result == null ? next : result.andExp(next);
+        }
+        return result;
+    }
+
     /**
      * {@inheritDoc}
      */
diff --git a/cayenne/src/main/java/org/apache/cayenne/map/ObjEntity.java 
b/cayenne/src/main/java/org/apache/cayenne/map/ObjEntity.java
index 0f792cb18..ef962bf6b 100644
--- a/cayenne/src/main/java/org/apache/cayenne/map/ObjEntity.java
+++ b/cayenne/src/main/java/org/apache/cayenne/map/ObjEntity.java
@@ -928,6 +928,17 @@ public class ObjEntity extends Entity<ObjEntity, 
ObjAttribute, ObjRelationship>
 
             Expression expression = (Expression) input;
 
+            if (expression.getType() == Expression.FULL_OBJECT && 
expression.getOperandCount() == 0) {
+                // A bare "self" reference carries no path, so there is 
nothing to rebase on the related
+                // entity. Resolve it to this entity's PK, which is what it 
means in the first place.
+                Collection<DbAttribute> pks = getDbEntity().getPrimaryKeys();
+                if (pks.size() > 1) {
+                    throw new CayenneRuntimeException("Can't transform a 
'self' expression rooted in '%s': " +
+                            "entity has more than one PK. Match by id map or 
ObjectId instead.", getName());
+                }
+                return 
ExpressionFactory.dbPathExp(pks.iterator().next().getName());
+            }
+
             if (expression.getType() != Expression.OBJ_PATH) {
                 return input;
             }
diff --git a/cayenne/src/main/java/org/apache/cayenne/query/SelectById.java 
b/cayenne/src/main/java/org/apache/cayenne/query/SelectById.java
index 532942134..c09f27be5 100644
--- a/cayenne/src/main/java/org/apache/cayenne/query/SelectById.java
+++ b/cayenne/src/main/java/org/apache/cayenne/query/SelectById.java
@@ -40,7 +40,34 @@ import static org.apache.cayenne.exp.ExpressionFactory.*;
  * A query to select objects by id.
  *
  * @since 4.0
+ * @deprecated this query is a thin wrapper around an {@link ObjectSelect} 
with a PK qualifier - use
+ *             {@link ObjectSelect} directly with one of the "id" expressions 
of the entity "self" property:
+ *             <table>
+ *               <caption>Migration</caption>
+ *               <tr><th>SelectById</th><th>ObjectSelect</th></tr>
+ *               <tr><td>{@code queryId(Artist.class, id)}</td>
+ *                   <td>{@code 
query(Artist.class).where(Artist.SELF.eqId(id))}</td></tr>
+ *               <tr><td>{@code queryIds(Artist.class, ids)}</td>
+ *                   <td>{@code 
query(Artist.class).where(Artist.SELF.idsIn(ids))}</td></tr>
+ *               <tr><td>{@code queryIdsCollection(Artist.class, ids)}</td>
+ *                   <td>{@code 
query(Artist.class).where(Artist.SELF.idsInCollection(ids))}</td></tr>
+ *               <tr><td>{@code queryMap(Artist.class, id)}</td>
+ *                   <td>{@code 
query(Artist.class).where(Artist.SELF.eqId(id))}</td></tr>
+ *               <tr><td>{@code queryMaps(Artist.class, ids)}</td>
+ *                   <td>{@code 
query(Artist.class).where(Artist.SELF.idMapsIn(ids))}</td></tr>
+ *               <tr><td>{@code queryMapsCollection(Artist.class, ids)}</td>
+ *                   <td>{@code 
query(Artist.class).where(Artist.SELF.idMapsInCollection(ids))}</td></tr>
+ *               <tr><td>{@code queryObjectId(Artist.class, id)}</td>
+ *                   <td>{@code 
query(Artist.class).where(Artist.SELF.eqId(id))}</td></tr>
+ *               <tr><td>{@code queryObjectIds(Artist.class, ids)}</td>
+ *                   <td>{@code 
query(Artist.class).where(Artist.SELF.objectIdsIn(ids))}</td></tr>
+ *               <tr><td>{@code queryObjectIdsCollection(Artist.class, 
ids)}</td>
+ *                   <td>{@code 
query(Artist.class).where(Artist.SELF.objectIdsInCollection(ids))}</td></tr>
+ *               <tr><td>{@code dataRowQuery*(..)}</td>
+ *                   <td>any of the above plus {@link 
ObjectSelect#fetchDataRows()}</td></tr>
+ *             </table>
  */
+@Deprecated(since = "5.0", forRemoval = true)
 public class SelectById<T> extends IndirectQuery implements Select<T> {
 
     private static final long serialVersionUID = -6589464349051607583L;
diff --git a/cayenne/src/test/java/org/apache/cayenne/CDOMapRelationshipIT.java 
b/cayenne/src/test/java/org/apache/cayenne/CDOMapRelationshipIT.java
index 9668f1653..2e6c65946 100644
--- a/cayenne/src/test/java/org/apache/cayenne/CDOMapRelationshipIT.java
+++ b/cayenne/src/test/java/org/apache/cayenne/CDOMapRelationshipIT.java
@@ -21,7 +21,7 @@ package org.apache.cayenne;
 import java.util.Map;
 
 import org.apache.cayenne.query.RefreshQuery;
-import org.apache.cayenne.query.SelectById;
+import org.apache.cayenne.query.ObjectSelect;
 import org.apache.cayenne.test.jdbc.TableHelper;
 import org.apache.cayenne.testdo.map_to_many.IdMapToMany;
 import org.apache.cayenne.testdo.map_to_many.MapToMany;
@@ -124,7 +124,8 @@ public class CDOMapRelationshipIT {
     public void readToManyPrefetching() throws Exception {
         createTestDataSet();
 
-        MapToMany o1 = SelectById.query(MapToMany.class, 
1).prefetch(MapToMany.TARGETS.disjoint()).selectOne(env.context());
+        MapToMany o1 = ObjectSelect.query(MapToMany.class)
+                
.where(MapToMany.SELF.eqId(1)).prefetch(MapToMany.TARGETS.disjoint()).selectOne(env.context());
         Map targets = o1.getTargets();
 
         assertFalse(((ValueHolder) targets).isFault());
diff --git a/cayenne/src/test/java/org/apache/cayenne/CDOSetRelationshipIT.java 
b/cayenne/src/test/java/org/apache/cayenne/CDOSetRelationshipIT.java
index 27193339b..18766e6ef 100644
--- a/cayenne/src/test/java/org/apache/cayenne/CDOSetRelationshipIT.java
+++ b/cayenne/src/test/java/org/apache/cayenne/CDOSetRelationshipIT.java
@@ -19,7 +19,7 @@
 package org.apache.cayenne;
 
 import org.apache.cayenne.query.RefreshQuery;
-import org.apache.cayenne.query.SelectById;
+import org.apache.cayenne.query.ObjectSelect;
 import org.apache.cayenne.test.jdbc.TableHelper;
 import org.apache.cayenne.testdo.relationships_set_to_many.SetToMany;
 import org.apache.cayenne.testdo.relationships_set_to_many.SetToManyTarget;
@@ -93,7 +93,8 @@ public class CDOSetRelationshipIT {
     public void readToManyPrefetching() throws Exception {
         createTestDataSet();
 
-        SetToMany o1 = SelectById.query(SetToMany.class, 
1).prefetch(SetToMany.TARGETS.disjoint()).selectOne(env.context());
+        SetToMany o1 = ObjectSelect.query(SetToMany.class)
+                
.where(SetToMany.SELF.eqId(1)).prefetch(SetToMany.TARGETS.disjoint()).selectOne(env.context());
 
         Set targets = o1.getTargets();
 
diff --git a/cayenne/src/test/java/org/apache/cayenne/MeaningfulFKIT.java 
b/cayenne/src/test/java/org/apache/cayenne/MeaningfulFKIT.java
index 520bac43c..4a5aa95f8 100644
--- a/cayenne/src/test/java/org/apache/cayenne/MeaningfulFKIT.java
+++ b/cayenne/src/test/java/org/apache/cayenne/MeaningfulFKIT.java
@@ -19,7 +19,7 @@
 
 package org.apache.cayenne;
 
-import org.apache.cayenne.query.SelectById;
+import org.apache.cayenne.query.ObjectSelect;
 import org.apache.cayenne.testdo.relationships.MeaningfulFK;
 import org.apache.cayenne.testdo.relationships.RelationshipHelper;
 import org.apache.cayenne.unit.CayenneProjects;
@@ -71,7 +71,8 @@ public class MeaningfulFKIT {
 
         env.context().commitChanges();
 
-        MeaningfulFK testObject2 = SelectById.query(MeaningfulFK.class, 
testObject.getObjectId()).selectOne(env.context());
+        MeaningfulFK testObject2 = ObjectSelect.query(MeaningfulFK.class)
+                
.where(MeaningfulFK.SELF.eqId(testObject.getObjectId())).selectOne(env.context());
         assertNotEquals(0, testObject2.getRelationshipHelperID());
     }
 }
diff --git 
a/cayenne/src/test/java/org/apache/cayenne/access/DataContextFlattenedAttributesIT.java
 
b/cayenne/src/test/java/org/apache/cayenne/access/DataContextFlattenedAttributesIT.java
index 324ad6a4a..0863c1b72 100644
--- 
a/cayenne/src/test/java/org/apache/cayenne/access/DataContextFlattenedAttributesIT.java
+++ 
b/cayenne/src/test/java/org/apache/cayenne/access/DataContextFlattenedAttributesIT.java
@@ -28,7 +28,6 @@ import org.apache.cayenne.map.DefaultEntityResultSegment;
 import org.apache.cayenne.query.ColumnSelect;
 import org.apache.cayenne.query.EJBQLQuery;
 import org.apache.cayenne.query.ObjectSelect;
-import org.apache.cayenne.query.SelectById;
 import org.apache.cayenne.reflect.PersistentDescriptor;
 import org.apache.cayenne.runtime.CayenneRuntime;
 import org.apache.cayenne.test.jdbc.TableHelper;
@@ -558,7 +557,8 @@ public class DataContextFlattenedAttributesIT {
         {
             // read and update
             ObjectContext context2 = runtime.newContext();
-            CompoundPainting o2 = SelectById.query(CompoundPainting.class, 
id).selectFirst(context2);
+            CompoundPainting o2 = ObjectSelect.query(CompoundPainting.class)
+                    
.where(CompoundPainting.SELF.eqId(id)).selectFirst(context2);
 
             o2.setArtistName("AX1");
             o2.setEstimatedPrice(BigDecimal.valueOf(2));
@@ -572,7 +572,8 @@ public class DataContextFlattenedAttributesIT {
         {
             // read and check
             ObjectContext context3 = runtime.newContext();
-            CompoundPainting o3 = SelectById.query(CompoundPainting.class, 
id).selectFirst(context3);
+            CompoundPainting o3 = ObjectSelect.query(CompoundPainting.class)
+                    
.where(CompoundPainting.SELF.eqId(id)).selectFirst(context3);
 
             assertEquals("AX1", o3.getArtistName());
             assertEquals(0, 
BigDecimal.valueOf(2).compareTo(o3.getEstimatedPrice()));
diff --git 
a/cayenne/src/test/java/org/apache/cayenne/access/EntityInheritanceIT.java 
b/cayenne/src/test/java/org/apache/cayenne/access/EntityInheritanceIT.java
index 58a9486f5..7e42c940e 100644
--- a/cayenne/src/test/java/org/apache/cayenne/access/EntityInheritanceIT.java
+++ b/cayenne/src/test/java/org/apache/cayenne/access/EntityInheritanceIT.java
@@ -20,7 +20,7 @@
 package org.apache.cayenne.access;
 
 import org.apache.cayenne.Cayenne;
-import org.apache.cayenne.query.SelectById;
+import org.apache.cayenne.query.ObjectSelect;
 import org.apache.cayenne.testdo.inheritance.BaseEntity;
 import org.apache.cayenne.testdo.inheritance.DirectToSubEntity;
 import org.apache.cayenne.testdo.inheritance.RelatedEntity;
@@ -97,7 +97,8 @@ public class EntityInheritanceIT {
         BaseEntity forPkLoadedEntity = Cayenne.objectForPK(env.context(), 
BaseEntity.class, subEntityId);
         assertEquals(forPkLoadedEntity.getClass(), SubEntity.class);
 
-        BaseEntity selectLoadedEntity = SelectById.query(BaseEntity.class, 
subEntityId).selectOne(env.context());
+        BaseEntity selectLoadedEntity = ObjectSelect.query(BaseEntity.class)
+                
.where(BaseEntity.SELF.eqId(subEntityId)).selectOne(env.context());
         assertEquals(selectLoadedEntity.getClass(), SubEntity.class);
     }
 }
diff --git 
a/cayenne/src/test/java/org/apache/cayenne/access/VerticalInheritanceIT.java 
b/cayenne/src/test/java/org/apache/cayenne/access/VerticalInheritanceIT.java
index f6ae0e2a2..a0216d5fb 100644
--- a/cayenne/src/test/java/org/apache/cayenne/access/VerticalInheritanceIT.java
+++ b/cayenne/src/test/java/org/apache/cayenne/access/VerticalInheritanceIT.java
@@ -27,7 +27,6 @@ import org.apache.cayenne.query.ColumnSelect;
 import org.apache.cayenne.query.EJBQLQuery;
 import org.apache.cayenne.query.ObjectSelect;
 import org.apache.cayenne.query.PrefetchTreeNode;
-import org.apache.cayenne.query.SelectById;
 import org.apache.cayenne.runtime.CayenneRuntime;
 import org.apache.cayenne.test.jdbc.TableHelper;
 import org.apache.cayenne.testdo.inheritance_vertical.*;
@@ -244,8 +243,8 @@ public class VerticalInheritanceIT {
                TableHelper ivSub3Table = env.table("IV_SUB3", "ID", 
"IV_ROOT_ID");
                ivSub3Table.insert(3, 1);
 
-               IvRoot root = SelectById.query(IvRoot.class, 
2).selectOne(env.context());
-               IvSub3 sub3 = SelectById.query(IvSub3.class, 
3).selectOne(env.context());
+               IvRoot root = 
ObjectSelect.query(IvRoot.class).where(IvRoot.SELF.eqId(2)).selectOne(env.context());
+               IvSub3 sub3 = 
ObjectSelect.query(IvSub3.class).where(IvSub3.SELF.eqId(3)).selectOne(env.context());
                sub3.setName("new name");
                sub3.setIvRoot(root);
 
@@ -254,7 +253,7 @@ public class VerticalInheritanceIT {
                env.context().commitChanges();
 
                ObjectContext cleanContext = runtime.newContext();
-               IvSub3 sub3Clean = SelectById.query(IvSub3.class, 
3).selectOne(cleanContext);
+               IvSub3 sub3Clean = 
ObjectSelect.query(IvSub3.class).where(IvSub3.SELF.eqId(3)).selectOne(cleanContext);
 
                assertNotNull(sub3Clean);
                assertNotSame(sub3, sub3Clean);
@@ -623,7 +622,8 @@ public class VerticalInheritanceIT {
                long id = Cayenne.longPKForObject(concrete);
                {
                        ObjectContext cleanContext = runtime.newContext();
-                       IvConcrete concreteFetched = 
SelectById.query(IvConcrete.class, id).selectOne(cleanContext);
+                       IvConcrete concreteFetched = 
ObjectSelect.query(IvConcrete.class)
+                                       
.where(IvConcrete.SELF.eqId(id)).selectOne(cleanContext);
                        assertNull(concreteFetched.getName());
                }
        }
@@ -646,7 +646,7 @@ public class VerticalInheritanceIT {
                long id = Cayenne.longPKForObject(impl);
                {
                        ObjectContext cleanContext = runtime.newContext();
-                       IvImpl implFetched = SelectById.query(IvImpl.class, 
id).selectOne(cleanContext);
+                       IvImpl implFetched = 
ObjectSelect.query(IvImpl.class).where(IvImpl.SELF.eqId(id)).selectOne(cleanContext);
                        assertEquals("Impl 1", implFetched.getName());
                        assertNull(implFetched.getOther1());
                }
@@ -665,8 +665,8 @@ public class VerticalInheritanceIT {
                ivBaseTable.insert(1, "Impl 1", "I");
                ivImplTable.insert(1, "attr1", 1);
 
-               IvImpl impl = SelectById.query(IvImpl.class, 
1).selectOne(env.context());
-               IvOther other = SelectById.query(IvOther.class, 
2).selectOne(env.context());
+               IvImpl impl = 
ObjectSelect.query(IvImpl.class).where(IvImpl.SELF.eqId(1)).selectOne(env.context());
+               IvOther other = 
ObjectSelect.query(IvOther.class).where(IvOther.SELF.eqId(2)).selectOne(env.context());
 
                impl.setOther3(other);
                env.context().commitChanges();
@@ -676,8 +676,8 @@ public class VerticalInheritanceIT {
 
                {
                        ObjectContext cleanContext = runtime.newContext();
-                       IvImpl implFetched = SelectById.query(IvImpl.class, 
1).selectOne(cleanContext);
-                       IvOther otherFetched = SelectById.query(IvOther.class, 
2).selectOne(cleanContext);
+                       IvImpl implFetched = 
ObjectSelect.query(IvImpl.class).where(IvImpl.SELF.eqId(1)).selectOne(cleanContext);
+                       IvOther otherFetched = 
ObjectSelect.query(IvOther.class).where(IvOther.SELF.eqId(2)).selectOne(cleanContext);
                        assertEquals("Impl 1", implFetched.getName());
                        assertEquals("attr1", implFetched.getAttr1());
                        assertEquals(implFetched.getOther3(), otherFetched);
@@ -688,7 +688,7 @@ public class VerticalInheritanceIT {
        public void deleteFlattenedNoValues() throws SQLException {
                ivAbstractTable.insert(1, null, "S");
 
-               IvConcrete concrete = SelectById.query(IvConcrete.class, 
1).selectOne(env.context());
+               IvConcrete concrete = 
ObjectSelect.query(IvConcrete.class).where(IvConcrete.SELF.eqId(1)).selectOne(env.context());
                assertNotNull(concrete);
                assertNull(concrete.getName());
 
@@ -704,7 +704,7 @@ public class VerticalInheritanceIT {
                ivAbstractTable.insert(1, null, "S");
                ivConcreteTable.insert(1, null, null);
 
-               IvConcrete concrete = SelectById.query(IvConcrete.class, 
1).selectOne(env.context());
+               IvConcrete concrete = 
ObjectSelect.query(IvConcrete.class).where(IvConcrete.SELF.eqId(1)).selectOne(env.context());
                assertNotNull(concrete);
                assertNull(concrete.getName());
 
@@ -720,7 +720,7 @@ public class VerticalInheritanceIT {
                ivAbstractTable.insert(1, null, "S");
                ivConcreteTable.insert(1, "test", null);
 
-               IvConcrete concrete = SelectById.query(IvConcrete.class, 
1).selectOne(env.context());
+               IvConcrete concrete = 
ObjectSelect.query(IvConcrete.class).where(IvConcrete.SELF.eqId(1)).selectOne(env.context());
                assertNotNull(concrete);
                assertEquals("test", concrete.getName());
 
@@ -745,7 +745,7 @@ public class VerticalInheritanceIT {
                ivAbstractTable.insert(2, null, "S");
                ivConcreteTable.insert(2, "Two", 1);
 
-               IvConcrete concrete = SelectById.query(IvConcrete.class, 
2).selectOne(env.context());
+               IvConcrete concrete = 
ObjectSelect.query(IvConcrete.class).where(IvConcrete.SELF.eqId(2)).selectOne(env.context());
                concrete.setRelatedAbstract(null);
 
                env.context().commitChanges();
@@ -753,7 +753,8 @@ public class VerticalInheritanceIT {
 
                {
                        ObjectContext cleanContext = runtime.newContext();
-                       IvConcrete concreteFetched = 
SelectById.query(IvConcrete.class, 2).selectOne(cleanContext);
+                       IvConcrete concreteFetched = 
ObjectSelect.query(IvConcrete.class)
+                                       
.where(IvConcrete.SELF.eqId(2)).selectOne(cleanContext);
                        assertEquals("Two", concreteFetched.getName());
                        assertNull(concreteFetched.getRelatedAbstract());
                }
@@ -1217,7 +1218,7 @@ public class VerticalInheritanceIT {
 
                assertEquals(1, ivImplTable.getRowCount());
                ObjectContext cleanContext = runtime.newContext();
-               IvImpl reread = SelectById.queryId(IvImpl.class, 
1).selectOne(cleanContext);
+               IvImpl reread = 
ObjectSelect.query(IvImpl.class).where(IvImpl.SELF.eqId(1)).selectOne(cleanContext);
                assertEquals("attr1-updated", reread.getAttr1());
        }
 
@@ -1264,7 +1265,7 @@ public class VerticalInheritanceIT {
 
                assertEquals(1, ivImplTable.getRowCount());
                ObjectContext cleanContext = runtime.newContext();
-               IvImpl reread = SelectById.queryId(IvImpl.class, 
1).selectOne(cleanContext);
+               IvImpl reread = 
ObjectSelect.query(IvImpl.class).where(IvImpl.SELF.eqId(1)).selectOne(cleanContext);
                assertEquals("attr1-second", reread.getAttr1());
        }
 
@@ -1278,7 +1279,7 @@ public class VerticalInheritanceIT {
                ivSub1Table.insert(1);
                ivSub1Sub1Table.insert(1, "sub1sub1name");
 
-               IvSub1Sub1 sub1Sub1 = SelectById.queryId(IvSub1Sub1.class, 
1).selectOne(env.context());
+               IvSub1Sub1 sub1Sub1 = 
ObjectSelect.query(IvSub1Sub1.class).where(IvSub1Sub1.SELF.eqId(1)).selectOne(env.context());
                assertEquals("sub1sub1name", sub1Sub1.getSub1Sub1Name());
 
                sub1Sub1.setSub1Sub1Name("sub1sub1name-updated");
@@ -1286,7 +1287,7 @@ public class VerticalInheritanceIT {
 
                assertEquals(1, ivSub1Sub1Table.getRowCount());
                ObjectContext cleanContext = runtime.newContext();
-               IvSub1Sub1 reread = SelectById.queryId(IvSub1Sub1.class, 
1).selectOne(cleanContext);
+               IvSub1Sub1 reread = 
ObjectSelect.query(IvSub1Sub1.class).where(IvSub1Sub1.SELF.eqId(1)).selectOne(cleanContext);
                assertEquals("sub1sub1name-updated", reread.getSub1Sub1Name());
        }
 }
diff --git 
a/cayenne/src/test/java/org/apache/cayenne/access/translator/select/QualifierTranslatorIT.java
 
b/cayenne/src/test/java/org/apache/cayenne/access/translator/select/QualifierTranslatorIT.java
index 668fbd6ae..c489ba39d 100644
--- 
a/cayenne/src/test/java/org/apache/cayenne/access/translator/select/QualifierTranslatorIT.java
+++ 
b/cayenne/src/test/java/org/apache/cayenne/access/translator/select/QualifierTranslatorIT.java
@@ -25,7 +25,6 @@ import org.apache.cayenne.ObjectId;
 import org.apache.cayenne.exp.ExpressionFactory;
 import org.apache.cayenne.CayenneRuntimeException;
 import org.apache.cayenne.query.ObjectSelect;
-import org.apache.cayenne.query.SelectById;
 import org.apache.cayenne.runtime.CayenneRuntime;
 import org.apache.cayenne.test.jdbc.TableHelper;
 import org.apache.cayenne.testdo.compound.CompoundFkTestEntity;
@@ -161,9 +160,6 @@ public class QualifierTranslatorIT {
                 
.where(CompoundPkTestEntity.SELF.eqId(id)).selectOne(env.context());
         assertNotNull(viaSelf);
         assertEquals("CCC", viaSelf.getName());
-
-        // must agree with the dedicated by-id query
-        assertSame(SelectById.queryObjectId(CompoundPkTestEntity.class, 
id).selectOne(env.context()), viaSelf);
     }
 
     /**
diff --git 
a/cayenne/src/test/java/org/apache/cayenne/commitlog/CommitLogFilterIT.java 
b/cayenne/src/test/java/org/apache/cayenne/commitlog/CommitLogFilterIT.java
index 552173312..cde6eddc4 100644
--- a/cayenne/src/test/java/org/apache/cayenne/commitlog/CommitLogFilterIT.java
+++ b/cayenne/src/test/java/org/apache/cayenne/commitlog/CommitLogFilterIT.java
@@ -25,7 +25,7 @@ import org.apache.cayenne.commitlog.db.AuditableChild1;
 import org.apache.cayenne.commitlog.db.AuditableChild1x;
 import org.apache.cayenne.commitlog.model.*;
 import org.apache.cayenne.commitlog.unit.AuditableRuntimeCase;
-import org.apache.cayenne.query.SelectById;
+import org.apache.cayenne.query.ObjectSelect;
 import org.apache.cayenne.configuration.runtime.CoreModule;
 import org.apache.cayenne.runtime.CayenneRuntimeBuilder;
 import org.junit.jupiter.api.BeforeEach;
@@ -87,7 +87,7 @@ public class CommitLogFilterIT extends AuditableRuntimeCase {
 
         auditable1.insert(1, "xx");
 
-        Auditable1 a1 = SelectById.query(Auditable1.class, 
1).selectOne(context);
+        Auditable1 a1 = 
ObjectSelect.query(Auditable1.class).where(Auditable1.SELF.eqId(1)).selectOne(context);
         a1.setCharProperty1("yy");
 
         ObjectId preCommitId = a1.getObjectId();
@@ -120,7 +120,7 @@ public class CommitLogFilterIT extends AuditableRuntimeCase 
{
         auditableChild1.insert(1, 1, "cc1");
         auditableChild1.insert(2, 1, "cc2");
 
-        Auditable1 a1 = SelectById.query(Auditable1.class, 
1).selectOne(context);
+        Auditable1 a1 = 
ObjectSelect.query(Auditable1.class).where(Auditable1.SELF.eqId(1)).selectOne(context);
         context.deleteObjects(a1.getChildren1());
         context.deleteObject(a1);
         context.commitChanges();
@@ -164,7 +164,8 @@ public class CommitLogFilterIT extends AuditableRuntimeCase 
{
         auditableChild1.insert(1, 1, "cc1");
         auditableChild1.insert(2, 1, "cc2");
 
-        AuditableChild1 ac1 = SelectById.query(AuditableChild1.class, 
2).selectOne(context);
+        AuditableChild1 ac1 = ObjectSelect.query(AuditableChild1.class)
+                .where(AuditableChild1.SELF.eqId(2)).selectOne(context);
         context.deleteObject(ac1);
         context.commitChanges();
 
@@ -194,7 +195,8 @@ public class CommitLogFilterIT extends AuditableRuntimeCase 
{
         auditableChild1x.insert(1, 1, "cc1");
         auditableChild1x.insert(2, 1, "cc2");
 
-        AuditableChild1x ac1 = SelectById.query(AuditableChild1x.class, 
2).selectOne(context);
+        AuditableChild1x ac1 = ObjectSelect.query(AuditableChild1x.class)
+                .where(AuditableChild1x.SELF.eqId(2)).selectOne(context);
         context.deleteObject(ac1);
         context.commitChanges();
 
@@ -228,12 +230,15 @@ public class CommitLogFilterIT extends 
AuditableRuntimeCase {
         auditableChild1.insert(2, 2, "cc2");
         auditableChild1.insert(3, null, "cc3");
 
-        AuditableChild1 ac1 = SelectById.query(AuditableChild1.class, 
1).selectOne(context);
-        AuditableChild1 ac2 = SelectById.query(AuditableChild1.class, 
2).selectOne(context);
-        AuditableChild1 ac3 = SelectById.query(AuditableChild1.class, 
3).selectOne(context);
+        AuditableChild1 ac1 = ObjectSelect.query(AuditableChild1.class)
+                .where(AuditableChild1.SELF.eqId(1)).selectOne(context);
+        AuditableChild1 ac2 = ObjectSelect.query(AuditableChild1.class)
+                .where(AuditableChild1.SELF.eqId(2)).selectOne(context);
+        AuditableChild1 ac3 = ObjectSelect.query(AuditableChild1.class)
+                .where(AuditableChild1.SELF.eqId(3)).selectOne(context);
 
-        Auditable1 a1 = SelectById.query(Auditable1.class, 
1).selectOne(context);
-        Auditable1 a2 = SelectById.query(Auditable1.class, 
2).selectOne(context);
+        Auditable1 a1 = 
ObjectSelect.query(Auditable1.class).where(Auditable1.SELF.eqId(1)).selectOne(context);
+        Auditable1 a2 = 
ObjectSelect.query(Auditable1.class).where(Auditable1.SELF.eqId(2)).selectOne(context);
 
         a1.removeFromChildren1(ac1);
         a1.addToChildren1(ac2);
@@ -297,11 +302,14 @@ public class CommitLogFilterIT extends 
AuditableRuntimeCase {
         auditableChild1.insert(2, null, "cc2");
         auditableChild1.insert(3, null, "cc3");
 
-        AuditableChild1 ac1 = SelectById.query(AuditableChild1.class, 
1).selectOne(context);
-        AuditableChild1 ac2 = SelectById.query(AuditableChild1.class, 
2).selectOne(context);
-        AuditableChild1 ac3 = SelectById.query(AuditableChild1.class, 
3).selectOne(context);
+        AuditableChild1 ac1 = ObjectSelect.query(AuditableChild1.class)
+                .where(AuditableChild1.SELF.eqId(1)).selectOne(context);
+        AuditableChild1 ac2 = ObjectSelect.query(AuditableChild1.class)
+                .where(AuditableChild1.SELF.eqId(2)).selectOne(context);
+        AuditableChild1 ac3 = ObjectSelect.query(AuditableChild1.class)
+                .where(AuditableChild1.SELF.eqId(3)).selectOne(context);
 
-        Auditable1 a1 = SelectById.query(Auditable1.class, 
1).selectOne(context);
+        Auditable1 a1 = 
ObjectSelect.query(Auditable1.class).where(Auditable1.SELF.eqId(1)).selectOne(context);
 
         a1.removeFromChildren1(ac1);
         a1.addToChildren1(ac2);
diff --git 
a/cayenne/src/test/java/org/apache/cayenne/commitlog/CommitLogFilter_All_FlattenedIT.java
 
b/cayenne/src/test/java/org/apache/cayenne/commitlog/CommitLogFilter_All_FlattenedIT.java
index 13eaac30c..1da500630 100644
--- 
a/cayenne/src/test/java/org/apache/cayenne/commitlog/CommitLogFilter_All_FlattenedIT.java
+++ 
b/cayenne/src/test/java/org/apache/cayenne/commitlog/CommitLogFilter_All_FlattenedIT.java
@@ -27,7 +27,7 @@ import org.apache.cayenne.commitlog.model.ObjectChange;
 import org.apache.cayenne.commitlog.model.ObjectChangeType;
 import org.apache.cayenne.commitlog.model.ToManyRelationshipChange;
 import org.apache.cayenne.commitlog.unit.FlattenedRuntimeCase;
-import org.apache.cayenne.query.SelectById;
+import org.apache.cayenne.query.ObjectSelect;
 import org.apache.cayenne.configuration.runtime.CoreModule;
 import org.apache.cayenne.runtime.CayenneRuntimeBuilder;
 import org.junit.jupiter.api.BeforeEach;
@@ -64,9 +64,9 @@ public class CommitLogFilter_All_FlattenedIT extends 
FlattenedRuntimeCase {
                e4.insert(12);
                e34.insert(1, 11);
 
-               E3 e3 = SelectById.query(E3.class, 1).selectOne(context);
-               E4 e4_1 = SelectById.query(E4.class, 11).selectOne(context);
-               E4 e4_2 = SelectById.query(E4.class, 12).selectOne(context);
+               E3 e3 = 
ObjectSelect.query(E3.class).where(E3.SELF.eqId(1)).selectOne(context);
+               E4 e4_1 = 
ObjectSelect.query(E4.class).where(E4.SELF.eqId(11)).selectOne(context);
+               E4 e4_2 = 
ObjectSelect.query(E4.class).where(E4.SELF.eqId(12)).selectOne(context);
 
                doAnswer((Answer<Object>) invocation -> {
 
diff --git 
a/cayenne/src/test/java/org/apache/cayenne/commitlog/CommitLogFilter_FilteredIT.java
 
b/cayenne/src/test/java/org/apache/cayenne/commitlog/CommitLogFilter_FilteredIT.java
index 4c624a749..efc53f8f8 100644
--- 
a/cayenne/src/test/java/org/apache/cayenne/commitlog/CommitLogFilter_FilteredIT.java
+++ 
b/cayenne/src/test/java/org/apache/cayenne/commitlog/CommitLogFilter_FilteredIT.java
@@ -31,7 +31,7 @@ import org.apache.cayenne.commitlog.model.ObjectChange;
 import org.apache.cayenne.commitlog.model.ObjectChangeType;
 import org.apache.cayenne.commitlog.model.ToManyRelationshipChange;
 import org.apache.cayenne.commitlog.unit.AuditableRuntimeCase;
-import org.apache.cayenne.query.SelectById;
+import org.apache.cayenne.query.ObjectSelect;
 import org.apache.cayenne.configuration.runtime.CoreModule;
 import org.apache.cayenne.runtime.CayenneRuntimeBuilder;
 import org.junit.jupiter.api.BeforeEach;
@@ -116,7 +116,7 @@ public class CommitLogFilter_FilteredIT extends 
AuditableRuntimeCase {
                        return null;
                }).when(mockListener).onPostCommit(any(ObjectContext.class), 
any(ChangeMap.class));
 
-               Auditable2 a1 = SelectById.query(Auditable2.class, 
1).selectOne(context);
+               Auditable2 a1 = 
ObjectSelect.query(Auditable2.class).where(Auditable2.SELF.eqId(1)).selectOne(context);
                a1.setCharProperty1("P1_2");
                a1.setCharProperty2("P2_2");
                context.commitChanges();
@@ -146,7 +146,7 @@ public class CommitLogFilter_FilteredIT extends 
AuditableRuntimeCase {
                        return null;
                }).when(mockListener).onPostCommit(any(ObjectContext.class), 
any(ChangeMap.class));
 
-               Auditable2 a1 = SelectById.query(Auditable2.class, 
1).selectOne(context);
+               Auditable2 a1 = 
ObjectSelect.query(Auditable2.class).where(Auditable2.SELF.eqId(1)).selectOne(context);
                context.deleteObject(a1);
                context.commitChanges();
 
@@ -160,11 +160,14 @@ public class CommitLogFilter_FilteredIT extends 
AuditableRuntimeCase {
                auditableChild1.insert(2, null, "cc2");
                auditableChild1.insert(3, null, "cc3");
 
-               final AuditableChild1 ac1 = 
SelectById.query(AuditableChild1.class, 1).selectOne(context);
-               final AuditableChild1 ac2 = 
SelectById.query(AuditableChild1.class, 2).selectOne(context);
-               final AuditableChild1 ac3 = 
SelectById.query(AuditableChild1.class, 3).selectOne(context);
+               final AuditableChild1 ac1 = 
ObjectSelect.query(AuditableChild1.class)
+                               
.where(AuditableChild1.SELF.eqId(1)).selectOne(context);
+               final AuditableChild1 ac2 = 
ObjectSelect.query(AuditableChild1.class)
+                               
.where(AuditableChild1.SELF.eqId(2)).selectOne(context);
+               final AuditableChild1 ac3 = 
ObjectSelect.query(AuditableChild1.class)
+                               
.where(AuditableChild1.SELF.eqId(3)).selectOne(context);
 
-               final Auditable1 a1 = SelectById.query(Auditable1.class, 
1).selectOne(context);
+               final Auditable1 a1 = 
ObjectSelect.query(Auditable1.class).where(Auditable1.SELF.eqId(1)).selectOne(context);
 
                doAnswer((Answer<Object>) invocation -> {
 
@@ -208,7 +211,7 @@ public class CommitLogFilter_FilteredIT extends 
AuditableRuntimeCase {
 
                auditable3.insert(1, "31", "32");
 
-               final Auditable3 a3 = SelectById.query(Auditable3.class, 
1).selectOne(context);
+               final Auditable3 a3 = 
ObjectSelect.query(Auditable3.class).where(Auditable3.SELF.eqId(1)).selectOne(context);
 
                doAnswer((Answer<Object>) invocation -> {
 
@@ -235,9 +238,9 @@ public class CommitLogFilter_FilteredIT extends 
AuditableRuntimeCase {
                auditable4.insert(11, "41", "42", 1);
                auditable4.insert(12, "43", "44", 1);
 
-               final Auditable3 a3 = SelectById.query(Auditable3.class, 
1).selectOne(context);
-               final Auditable4 a41 = SelectById.query(Auditable4.class, 
11).selectOne(context);
-               final Auditable4 a42 = SelectById.query(Auditable4.class, 
12).selectOne(context);
+               final Auditable3 a3 = 
ObjectSelect.query(Auditable3.class).where(Auditable3.SELF.eqId(1)).selectOne(context);
+               final Auditable4 a41 = 
ObjectSelect.query(Auditable4.class).where(Auditable4.SELF.eqId(11)).selectOne(context);
+               final Auditable4 a42 = 
ObjectSelect.query(Auditable4.class).where(Auditable4.SELF.eqId(12)).selectOne(context);
 
                doAnswer((Answer<Object>) invocation -> {
 
@@ -264,9 +267,9 @@ public class CommitLogFilter_FilteredIT extends 
AuditableRuntimeCase {
                auditable3.insert(2, "33", "34");
                auditable4.insert(11, "41", "41", 1);
 
-               final Auditable3 a32 = SelectById.query(Auditable3.class, 
2).selectOne(context);
+               final Auditable3 a32 = 
ObjectSelect.query(Auditable3.class).where(Auditable3.SELF.eqId(2)).selectOne(context);
 
-               final Auditable4 a4 = SelectById.query(Auditable4.class, 
11).selectOne(context);
+               final Auditable4 a4 = 
ObjectSelect.query(Auditable4.class).where(Auditable4.SELF.eqId(11)).selectOne(context);
 
                doAnswer((Answer<Object>) invocation -> {
 
diff --git 
a/cayenne/src/test/java/org/apache/cayenne/commitlog/CommitLogFilter_ListenerInducedChangesIT.java
 
b/cayenne/src/test/java/org/apache/cayenne/commitlog/CommitLogFilter_ListenerInducedChangesIT.java
index 7fcf8a232..00eb3d9a3 100644
--- 
a/cayenne/src/test/java/org/apache/cayenne/commitlog/CommitLogFilter_ListenerInducedChangesIT.java
+++ 
b/cayenne/src/test/java/org/apache/cayenne/commitlog/CommitLogFilter_ListenerInducedChangesIT.java
@@ -29,7 +29,7 @@ import org.apache.cayenne.commitlog.model.ChangeMap;
 import org.apache.cayenne.commitlog.model.ObjectChange;
 import org.apache.cayenne.commitlog.model.ObjectChangeType;
 import org.apache.cayenne.commitlog.unit.AuditableRuntimeCase;
-import org.apache.cayenne.query.SelectById;
+import org.apache.cayenne.query.ObjectSelect;
 import org.apache.cayenne.configuration.runtime.CoreModule;
 import org.apache.cayenne.runtime.CayenneRuntimeBuilder;
 import org.junit.jupiter.api.BeforeEach;
@@ -111,7 +111,8 @@ public class CommitLogFilter_ListenerInducedChangesIT 
extends AuditableRuntimeCa
                final DeleteListener listener = new DeleteListener();
                runtime.getDataDomain().addListener(listener);
 
-               final Auditable1 a1 = SelectById.query(Auditable1.class, 
1).prefetch(Auditable1.CHILDREN1.joint())
+               final Auditable1 a1 = ObjectSelect.query(Auditable1.class)
+                               
.where(Auditable1.SELF.eqId(1)).prefetch(Auditable1.CHILDREN1.joint())
                                .selectFirst(context);
                a1.setCharProperty1("zz");
 
@@ -152,7 +153,8 @@ public class CommitLogFilter_ListenerInducedChangesIT 
extends AuditableRuntimeCa
                final UpdateListener listener = new UpdateListener();
                runtime.getDataDomain().addListener(listener);
 
-               final Auditable1 a1 = SelectById.query(Auditable1.class, 
1).prefetch(Auditable1.CHILDREN1.joint())
+               final Auditable1 a1 = ObjectSelect.query(Auditable1.class)
+                               
.where(Auditable1.SELF.eqId(1)).prefetch(Auditable1.CHILDREN1.joint())
                                .selectFirst(context);
                a1.setCharProperty1("zz");
 
diff --git 
a/cayenne/src/test/java/org/apache/cayenne/exp/property/EntityPropertyIdIT.java 
b/cayenne/src/test/java/org/apache/cayenne/exp/property/EntityPropertyIdIT.java
new file mode 100644
index 000000000..0b3d15be7
--- /dev/null
+++ 
b/cayenne/src/test/java/org/apache/cayenne/exp/property/EntityPropertyIdIT.java
@@ -0,0 +1,161 @@
+/*****************************************************************
+ *   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.exp.property;
+
+import org.apache.cayenne.CayenneRuntimeException;
+import org.apache.cayenne.ObjectId;
+import org.apache.cayenne.exp.Expression;
+import org.apache.cayenne.exp.ExpressionFactory;
+import org.apache.cayenne.query.ObjectSelect;
+import org.apache.cayenne.test.jdbc.TableHelper;
+import org.apache.cayenne.testdo.compound.CompoundFkTestEntity;
+import org.apache.cayenne.testdo.compound.CompoundPkTestEntity;
+import org.apache.cayenne.unit.CayenneProjects;
+import org.apache.cayenne.unit.CayenneTestsEnv;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.RegisterExtension;
+
+import java.sql.SQLException;
+import java.util.List;
+import java.util.Map;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertSame;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+public class EntityPropertyIdIT {
+
+    @RegisterExtension
+    static final CayenneTestsEnv env = 
CayenneTestsEnv.forProject(CayenneProjects.COMPOUND_PROJECT);
+
+    private static final Map<String, ?> PK_1 = Map.of("KEY1", "PK1", "KEY2", 
"PK2");
+    private static final Map<String, ?> PK_2 = Map.of("KEY1", "PK3", "KEY2", 
"PK4");
+
+    @BeforeEach
+    public void seed() throws SQLException {
+        TableHelper pk = env.table("COMPOUND_PK_TEST", "KEY1", "KEY2", "NAME");
+        pk.insert("PK1", "PK2", "BBB");
+        pk.insert("PK3", "PK4", "CCC");
+
+        TableHelper fk = env.table("COMPOUND_FK_TEST", "PKEY", "F_KEY1", 
"F_KEY2", "NAME");
+        fk.insert(1, "PK1", "PK2", "FK1");
+        fk.insert(2, "PK3", "PK4", "FK2");
+    }
+
+    // --- "self" property: an empty path ---
+
+    @Test
+    public void selfEqIdMap() {
+        CompoundPkTestEntity o = ObjectSelect.query(CompoundPkTestEntity.class)
+                
.where(CompoundPkTestEntity.SELF.eqIdMap(PK_2)).selectOne(env.context());
+        assertNotNull(o);
+        assertEquals("CCC", o.getName());
+    }
+
+    @Test
+    public void selfEqIdMapMatchesExplicitDbExpression() {
+        CompoundPkTestEntity viaProperty = 
ObjectSelect.query(CompoundPkTestEntity.class)
+                
.where(CompoundPkTestEntity.SELF.eqIdMap(PK_2)).selectOne(env.context());
+
+        // the same match, spelled out as raw db paths
+        CompoundPkTestEntity viaExpression = 
ObjectSelect.query(CompoundPkTestEntity.class)
+                .where(ExpressionFactory.matchAllDbExp(PK_2, 
Expression.EQUAL_TO)).selectOne(env.context());
+
+        assertSame(viaExpression, viaProperty);
+    }
+
+    @Test
+    public void selfNeqIdMap() {
+        List<CompoundPkTestEntity> list = 
ObjectSelect.query(CompoundPkTestEntity.class)
+                
.where(CompoundPkTestEntity.SELF.neqIdMap(PK_1)).select(env.context());
+        assertEquals(1, list.size());
+        assertEquals("CCC", list.get(0).getName());
+    }
+
+    @Test
+    public void selfIdMapsIn() {
+        List<CompoundPkTestEntity> list = 
ObjectSelect.query(CompoundPkTestEntity.class)
+                .where(CompoundPkTestEntity.SELF.idMapsIn(PK_1, PK_2))
+                
.orderBy(CompoundPkTestEntity.NAME.asc()).select(env.context());
+        assertEquals(2, list.size());
+        assertEquals("BBB", list.get(0).getName());
+        assertEquals("CCC", list.get(1).getName());
+    }
+
+    @Test
+    public void selfObjectIdsIn() {
+        ObjectId id1 = ObjectId.of("CompoundPkTestEntity", PK_1);
+        ObjectId id2 = ObjectId.of("CompoundPkTestEntity", PK_2);
+
+        List<CompoundPkTestEntity> list = 
ObjectSelect.query(CompoundPkTestEntity.class)
+                .where(CompoundPkTestEntity.SELF.objectIdsIn(id1, id2))
+                
.orderBy(CompoundPkTestEntity.NAME.asc()).select(env.context());
+        assertEquals(2, list.size());
+        assertEquals("BBB", list.get(0).getName());
+        assertEquals("CCC", list.get(1).getName());
+    }
+
+    // --- to-one relationship property: a non-empty path ---
+
+    @Test
+    public void toOneEqIdMap() {
+        CompoundFkTestEntity o = ObjectSelect.query(CompoundFkTestEntity.class)
+                
.where(CompoundFkTestEntity.TO_COMPOUND_PK.eqIdMap(PK_2)).selectOne(env.context());
+        assertNotNull(o);
+        assertEquals("FK2", o.getName());
+    }
+
+    @Test
+    public void toOneIdMapsIn() {
+        List<CompoundFkTestEntity> list = 
ObjectSelect.query(CompoundFkTestEntity.class)
+                .where(CompoundFkTestEntity.TO_COMPOUND_PK.idMapsIn(PK_1, 
PK_2))
+                
.orderBy(CompoundFkTestEntity.NAME.asc()).select(env.context());
+        assertEquals(2, list.size());
+        assertEquals("FK1", list.get(0).getName());
+    }
+
+    @Test
+    public void toOneObjectIdsIn() {
+        ObjectId id1 = ObjectId.of("CompoundPkTestEntity", PK_1);
+        List<CompoundFkTestEntity> list = 
ObjectSelect.query(CompoundFkTestEntity.class)
+                
.where(CompoundFkTestEntity.TO_COMPOUND_PK.objectIdsIn(id1)).select(env.context());
+        assertEquals(1, list.size());
+        assertEquals("FK1", list.get(0).getName());
+    }
+
+    // --- edge cases ---
+
+    @Test
+    public void emptyIdCollectionMatchesNothing() {
+        List<CompoundPkTestEntity> list = 
ObjectSelect.query(CompoundPkTestEntity.class)
+                
.where(CompoundPkTestEntity.SELF.idMapsInCollection(List.of())).select(env.context());
+        assertTrue(list.isEmpty());
+    }
+
+    @Test
+    public void emptyIdMapFails() {
+        CayenneRuntimeException e = assertThrows(CayenneRuntimeException.class,
+                () -> CompoundPkTestEntity.SELF.eqIdMap(Map.of()));
+        assertTrue(e.getMessage().contains("Null or empty id map"), 
e.getMessage());
+    }
+}
diff --git 
a/cayenne/src/test/java/org/apache/cayenne/query/ObjectSelect_ByIdIT.java 
b/cayenne/src/test/java/org/apache/cayenne/query/ObjectSelect_ByIdIT.java
new file mode 100644
index 000000000..ab3509a11
--- /dev/null
+++ b/cayenne/src/test/java/org/apache/cayenne/query/ObjectSelect_ByIdIT.java
@@ -0,0 +1,356 @@
+/*****************************************************************
+ *   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 org.apache.cayenne.Cayenne;
+import org.apache.cayenne.DataRow;
+import org.apache.cayenne.ObjectId;
+import org.apache.cayenne.ResultBatchIterator;
+import org.apache.cayenne.ResultIterator;
+import org.apache.cayenne.test.jdbc.TableHelper;
+import org.apache.cayenne.testdo.testmap.Artist;
+import org.apache.cayenne.testdo.testmap.Painting;
+import org.apache.cayenne.unit.CayenneProjects;
+import org.apache.cayenne.unit.CayenneTestsEnv;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.RegisterExtension;
+
+import java.sql.Types;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import static java.util.Collections.singletonMap;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertSame;
+
+public class ObjectSelect_ByIdIT {
+
+    @RegisterExtension
+    static final CayenneTestsEnv env = 
CayenneTestsEnv.forProject(CayenneProjects.TESTMAP_PROJECT);
+
+    private TableHelper tArtist;
+    private TableHelper tPainting;
+
+    @BeforeEach
+    public void setUp() {
+        tArtist = env.table("ARTIST").setColumns("ARTIST_ID", "ARTIST_NAME");
+        tPainting = env.table("PAINTING").setColumns("PAINTING_ID", 
"ARTIST_ID", "PAINTING_TITLE")
+                .setColumnTypes(Types.INTEGER, Types.BIGINT, Types.VARCHAR);
+    }
+
+    private void createTwoArtists() throws Exception {
+        tArtist.insert(2, "artist2");
+        tArtist.insert(3, "artist3");
+    }
+
+    // --- scalar ids ---
+
+    @Test
+    public void intPk() throws Exception {
+        createTwoArtists();
+
+        Artist a3 = 
ObjectSelect.query(Artist.class).where(Artist.SELF.eqId(3)).selectOne(env.context());
+        assertNotNull(a3);
+        assertEquals("artist3", a3.getArtistName());
+
+        Artist a2 = 
ObjectSelect.query(Artist.class).where(Artist.SELF.eqId(2)).selectOne(env.context());
+        assertNotNull(a2);
+        assertEquals("artist2", a2.getArtistName());
+    }
+
+    @Test
+    public void intPkSelectFirst() throws Exception {
+        createTwoArtists();
+
+        Artist a3 = 
ObjectSelect.query(Artist.class).where(Artist.SELF.eqId(3)).selectFirst(env.context());
+        assertNotNull(a3);
+        assertEquals("artist3", a3.getArtistName());
+    }
+
+    @Test
+    public void nullPk() {
+        List<Artist> artists = ObjectSelect.query(Artist.class)
+                .where(Artist.SELF.eqId(null)).select(env.context());
+        assertEquals(0, artists.size());
+    }
+
+    @Test
+    public void intPkMulti() throws Exception {
+        createTwoArtists();
+
+        List<Artist> artists = ObjectSelect.query(Artist.class)
+                .where(Artist.SELF.idsIn(2, 
3)).orderBy(Artist.ARTIST_NAME.asc()).select(env.context());
+        assertEquals(2, artists.size());
+        assertEquals("artist2", artists.get(0).getArtistName());
+        assertEquals("artist3", artists.get(1).getArtistName());
+    }
+
+    @Test
+    public void intPkCollection() throws Exception {
+        createTwoArtists();
+
+        List<Artist> artists = ObjectSelect.query(Artist.class)
+                .where(Artist.SELF.idsInCollection(Arrays.asList(2, 3)))
+                .orderBy(Artist.ARTIST_NAME.asc()).select(env.context());
+        assertEquals(2, artists.size());
+    }
+
+    @Test
+    public void emptyPkCollection() {
+        List<Artist> artists = ObjectSelect.query(Artist.class)
+                
.where(Artist.SELF.idsInCollection(Collections.emptyList())).select(env.context());
+        assertEquals(0, artists.size());
+    }
+
+    // --- map ids ---
+
+    @Test
+    public void mapPk() throws Exception {
+        createTwoArtists();
+
+        Artist a3 = ObjectSelect.query(Artist.class)
+                
.where(Artist.SELF.eqIdMap(singletonMap(Artist.ARTIST_ID_PK_COLUMN, 3)))
+                .selectOne(env.context());
+        assertNotNull(a3);
+        assertEquals("artist3", a3.getArtistName());
+    }
+
+    @Test
+    public void mapPkMulti() throws Exception {
+        createTwoArtists();
+
+        Map<String, ?> id2 = singletonMap(Artist.ARTIST_ID_PK_COLUMN, 2);
+        Map<String, ?> id3 = singletonMap(Artist.ARTIST_ID_PK_COLUMN, 3);
+
+        List<Artist> artists = ObjectSelect.query(Artist.class)
+                .where(Artist.SELF.idMapsIn(id2, id3))
+                .orderBy(Artist.ARTIST_NAME.asc()).select(env.context());
+        assertEquals(2, artists.size());
+        assertEquals("artist2", artists.get(0).getArtistName());
+    }
+
+    @Test
+    public void mapPkCollection() throws Exception {
+        createTwoArtists();
+
+        List<Map<String, ?>> ids = Arrays.asList(
+                singletonMap(Artist.ARTIST_ID_PK_COLUMN, 2),
+                singletonMap(Artist.ARTIST_ID_PK_COLUMN, 3));
+
+        List<Artist> artists = ObjectSelect.query(Artist.class)
+                
.where(Artist.SELF.idMapsInCollection(ids)).select(env.context());
+        assertEquals(2, artists.size());
+    }
+
+    @Test
+    public void emptyMapPkCollection() {
+        List<Artist> artists = ObjectSelect.query(Artist.class)
+                
.where(Artist.SELF.idMapsInCollection(Collections.emptyList())).select(env.context());
+        assertEquals(0, artists.size());
+    }
+
+    // --- ObjectId ids ---
+
+    @Test
+    public void objectIdPk() throws Exception {
+        createTwoArtists();
+
+        ObjectId id = ObjectId.of("Artist", Artist.ARTIST_ID_PK_COLUMN, 3);
+        Artist a3 = 
ObjectSelect.query(Artist.class).where(Artist.SELF.eqId(id)).selectOne(env.context());
+        assertNotNull(a3);
+        assertEquals("artist3", a3.getArtistName());
+    }
+
+    @Test
+    public void objectIdPkMulti() throws Exception {
+        createTwoArtists();
+
+        ObjectId id2 = ObjectId.of("Artist", Artist.ARTIST_ID_PK_COLUMN, 2);
+        ObjectId id3 = ObjectId.of("Artist", Artist.ARTIST_ID_PK_COLUMN, 3);
+
+        List<Artist> artists = ObjectSelect.query(Artist.class)
+                .where(Artist.SELF.objectIdsIn(id2, id3))
+                .orderBy(Artist.ARTIST_NAME.asc()).select(env.context());
+        assertEquals(2, artists.size());
+        assertEquals("artist2", artists.get(0).getArtistName());
+    }
+
+    @Test
+    public void objectIdPkCollection() throws Exception {
+        createTwoArtists();
+
+        List<ObjectId> ids = Arrays.asList(
+                ObjectId.of("Artist", Artist.ARTIST_ID_PK_COLUMN, 2),
+                ObjectId.of("Artist", Artist.ARTIST_ID_PK_COLUMN, 3));
+
+        List<Artist> artists = ObjectSelect.query(Artist.class)
+                
.where(Artist.SELF.objectIdsInCollection(ids)).select(env.context());
+        assertEquals(2, artists.size());
+    }
+
+    // --- DataRows: the "dataRowQuery*" equivalent is chaining 
fetchDataRows() ---
+
+    @Test
+    public void dataRowIntPk() throws Exception {
+        createTwoArtists();
+
+        DataRow row = 
ObjectSelect.query(Artist.class).where(Artist.SELF.eqId(3))
+                .fetchDataRows().selectOne(env.context());
+        assertNotNull(row);
+        assertEquals("artist3", row.get("ARTIST_NAME"));
+    }
+
+    @Test
+    public void dataRowIntPkMulti() throws Exception {
+        createTwoArtists();
+
+        List<DataRow> rows = 
ObjectSelect.query(Artist.class).where(Artist.SELF.idsIn(2, 3))
+                .fetchDataRows().select(env.context());
+        assertEquals(2, rows.size());
+    }
+
+    @Test
+    public void dataRowObjectIdPk() throws Exception {
+        createTwoArtists();
+
+        ObjectId id = ObjectId.of("Artist", Artist.ARTIST_ID_PK_COLUMN, 3);
+        DataRow row = 
ObjectSelect.query(Artist.class).where(Artist.SELF.eqId(id))
+                .fetchDataRows().selectOne(env.context());
+        assertEquals("artist3", row.get("ARTIST_NAME"));
+    }
+
+    // --- caching and prefetching still work off a by-id qualifier ---
+
+    @Test
+    public void localCache() throws Exception {
+        createTwoArtists();
+
+        final Artist[] a3 = new Artist[1];
+
+        assertEquals(1, env.runWithQueryCounter(() -> {
+            a3[0] = ObjectSelect.query(Artist.class).where(Artist.SELF.eqId(3))
+                    .localCache("g1").selectOne(env.context());
+            assertNotNull(a3[0]);
+            assertEquals("artist3", a3[0].getArtistName());
+        }));
+
+        env.runWithQueriesBlocked(() -> {
+            Artist a3cached = 
ObjectSelect.query(Artist.class).where(Artist.SELF.eqId(3))
+                    .localCache("g1").selectOne(env.context());
+            assertSame(a3[0], a3cached);
+        });
+
+        env.context().performGenericQuery(new RefreshQuery("g1"));
+
+        assertEquals(1, env.runWithQueryCounter(() -> 
ObjectSelect.query(Artist.class)
+                
.where(Artist.SELF.eqId(3)).localCache("g1").selectOne(env.context())));
+    }
+
+    @Test
+    public void prefetch() throws Exception {
+        createTwoArtists();
+        tPainting.insert(45, 3, "One");
+        tPainting.insert(48, 3, "Two");
+
+        Artist a3 = ObjectSelect.query(Artist.class).where(Artist.SELF.eqId(3))
+                .prefetch(Artist.PAINTING_ARRAY.joint())
+                .selectOne(env.context());
+
+        env.runWithQueriesBlocked(() -> {
+            assertNotNull(a3);
+            assertEquals("artist3", a3.getArtistName());
+            assertEquals(2, a3.getPaintingArray().size());
+
+            a3.getPaintingArray().get(0).getPaintingTitle();
+            a3.getPaintingArray().get(1).getPaintingTitle();
+        });
+    }
+
+    /**
+     * A disjoint prefetch rebases the query qualifier onto the prefetched 
entity. A bare "self"
+     * reference has no path to rebase, so it must be resolved to the root PK 
first - otherwise it
+     * silently reads as the *target* entity's PK.
+     */
+    @Test
+    public void prefetchDisjoint() throws Exception {
+        createTwoArtists();
+        tPainting.insert(45, 3, "One");
+        tPainting.insert(48, 3, "Two");
+
+        Artist a3 = ObjectSelect.query(Artist.class).where(Artist.SELF.eqId(3))
+                .prefetch(Artist.PAINTING_ARRAY.disjoint())
+                .selectOne(env.context());
+
+        env.runWithQueriesBlocked(() -> {
+            assertNotNull(a3);
+            assertEquals(2, a3.getPaintingArray().size());
+        });
+    }
+
+    // --- iterated results, mirroring SelectByIdIteratedQueryIT ---
+
+    @Test
+    public void queryWithBatchIterator() throws Exception {
+        createSixPaintings();
+
+        try (ResultBatchIterator<Painting> iterator = 
ObjectSelect.query(Painting.class)
+                .where(Painting.SELF.idsInCollection(Arrays.asList(1, 2, 3, 4, 
5, 6)))
+                .batchIterator(env.context(), 4)) {
+
+            int count = 0;
+            while (iterator.hasNext()) {
+                count++;
+                for (Painting painting : iterator.next()) {
+                    assertEquals("painting" + 
Cayenne.longPKForObject(painting), painting.getPaintingTitle());
+                }
+            }
+            assertEquals(2, count);
+        }
+    }
+
+    @Test
+    public void queryWithIterator() throws Exception {
+        createSixPaintings();
+
+        try (ResultIterator<Painting> iterator = 
ObjectSelect.query(Painting.class)
+                .where(Painting.SELF.idsInCollection(Arrays.asList(1, 2, 3, 4, 
5, 6)))
+                .iterator(env.context())) {
+
+            int count = 0;
+            while (iterator.hasNextRow()) {
+                count++;
+                Painting painting = iterator.nextRow();
+                assertEquals("painting" + Cayenne.longPKForObject(painting), 
painting.getPaintingTitle());
+            }
+            assertEquals(6, count);
+        }
+    }
+
+    private void createSixPaintings() throws Exception {
+        tArtist.insert(1, "artist1");
+        for (int i = 1; i <= 6; i++) {
+            tPainting.insert(i, 1, "painting" + i);
+        }
+    }
+}
diff --git 
a/cayenne/src/test/java/org/apache/cayenne/query/SelectByIdIteratedQueryIT.java 
b/cayenne/src/test/java/org/apache/cayenne/query/SelectByIdIteratedQueryIT.java
index 8f00eeccf..ab9dbbf25 100644
--- 
a/cayenne/src/test/java/org/apache/cayenne/query/SelectByIdIteratedQueryIT.java
+++ 
b/cayenne/src/test/java/org/apache/cayenne/query/SelectByIdIteratedQueryIT.java
@@ -39,6 +39,7 @@ import java.util.List;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 
 
+@SuppressWarnings("removal") // dedicated coverage for the deprecated 
SelectById
 public class SelectByIdIteratedQueryIT {
 
     @RegisterExtension
diff --git a/cayenne/src/test/java/org/apache/cayenne/query/SelectByIdTest.java 
b/cayenne/src/test/java/org/apache/cayenne/query/SelectByIdTest.java
index 98c27e287..157c41525 100644
--- a/cayenne/src/test/java/org/apache/cayenne/query/SelectByIdTest.java
+++ b/cayenne/src/test/java/org/apache/cayenne/query/SelectByIdTest.java
@@ -26,6 +26,7 @@ import org.junit.jupiter.api.Test;
 
 import static org.junit.jupiter.api.Assertions.*;
 
+@SuppressWarnings("removal") // dedicated coverage for the deprecated 
SelectById
 public class SelectByIdTest {
 
        @Test
diff --git 
a/cayenne/src/test/java/org/apache/cayenne/query/SelectById_RunIT.java 
b/cayenne/src/test/java/org/apache/cayenne/query/SelectById_RunIT.java
index b63ff2694..5a7605861 100644
--- a/cayenne/src/test/java/org/apache/cayenne/query/SelectById_RunIT.java
+++ b/cayenne/src/test/java/org/apache/cayenne/query/SelectById_RunIT.java
@@ -39,6 +39,7 @@ import java.util.Map;
 import static java.util.Collections.singletonMap;
 import static org.junit.jupiter.api.Assertions.*;
 
+@SuppressWarnings("removal") // dedicated coverage for the deprecated 
SelectById
 public class SelectById_RunIT {
 
     @RegisterExtension
diff --git 
a/cayenne/src/test/java/org/apache/cayenne/value/json/JsonTypeIT.java 
b/cayenne/src/test/java/org/apache/cayenne/value/json/JsonTypeIT.java
index 1b7eb272b..0f7e6ab5f 100644
--- a/cayenne/src/test/java/org/apache/cayenne/value/json/JsonTypeIT.java
+++ b/cayenne/src/test/java/org/apache/cayenne/value/json/JsonTypeIT.java
@@ -19,7 +19,7 @@
 
 package org.apache.cayenne.value.json;
 
-import org.apache.cayenne.query.SelectById;
+import org.apache.cayenne.query.ObjectSelect;
 import org.apache.cayenne.testdo.json.JsonOther;
 import org.apache.cayenne.testdo.json.JsonVarchar;
 import org.apache.cayenne.unit.CayenneProjects;
@@ -660,7 +660,8 @@ public class JsonTypeIT {
         jsonInsert.setData(new Json(jsonString));
         env.context().commitChanges();
 
-        JsonOther jsonSelect = 
env.context().selectOne(SelectById.query(JsonOther.class, 
jsonInsert.getObjectId()));
+        JsonOther jsonSelect = 
env.context().selectOne(ObjectSelect.query(JsonOther.class)
+                .where(JsonOther.SELF.eqId(jsonInsert.getObjectId())));
         assertEquals(jsonInsert.getData(), jsonSelect.getData());
     }
 
@@ -669,7 +670,8 @@ public class JsonTypeIT {
         jsonInsert.setData(new Json(jsonString));
         env.context().commitChanges();
 
-        JsonVarchar jsonSelect = 
env.context().selectOne(SelectById.query(JsonVarchar.class, 
jsonInsert.getObjectId()));
+        JsonVarchar jsonSelect = 
env.context().selectOne(ObjectSelect.query(JsonVarchar.class)
+                .where(JsonVarchar.SELF.eqId(jsonInsert.getObjectId())));
         assertEquals(jsonInsert.getData(), jsonSelect.getData());
     }
 }

Reply via email to