You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cayenne.apache.org by nt...@apache.org on 2024/11/05 16:10:34 UTC

(cayenne) branch master updated: CAY-2859 Redesign SelectById factory methods

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

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


The following commit(s) were added to refs/heads/master by this push:
     new b6000d6d9 CAY-2859 Redesign SelectById factory methods
b6000d6d9 is described below

commit b6000d6d9aa0fcbc6ee659a4364ddd0b2ddf338b
Author: Nikita Timofeev <st...@gmail.com>
AuthorDate: Tue Nov 5 20:10:20 2024 +0400

    CAY-2859 Redesign SelectById factory methods
---
 RELEASE-NOTES.txt                                  |   1 +
 UPGRADE.txt                                        |   5 +
 .../java/org/apache/cayenne/query/SelectById.java  | 301 ++++++++++++++++++-
 .../org/apache/cayenne/query/SelectById_RunIT.java | 320 ++++++++++++++++++---
 4 files changed, 574 insertions(+), 53 deletions(-)

diff --git a/RELEASE-NOTES.txt b/RELEASE-NOTES.txt
index e4f34f787..51ebf70d6 100644
--- a/RELEASE-NOTES.txt
+++ b/RELEASE-NOTES.txt
@@ -13,6 +13,7 @@ Date:
 ----------------------------------
 Changes/New Features:
 
+CAY-2859 Redesign SelectById factory methods
 CAY-2871 QualifierTranslator breaks on a relationship with a compound FK
 CAY-2872 CayenneModeler "Documentation" link is broken
 CAY-2873 Change Orderings.orderedList() to accept a Collection rather than a List
diff --git a/UPGRADE.txt b/UPGRADE.txt
index fd6bf83b4..95bccd5f9 100644
--- a/UPGRADE.txt
+++ b/UPGRADE.txt
@@ -5,6 +5,11 @@ IMPORTANT: be sure to read all notes for the intermediate releases between your
            current release and the release you are upgrading to.
 -------------------------------------------------------------------------------
 
+UPGRADING TO 5.0.M2
+
+* Per CAY-2859 SelectById query factory methods are redesigned with a bunch of old methods deprecated,
+so you should update your calls accordingly.
+
 UPGRADING TO 5.0.M1
 
 * Per CAY-2737 All code deprecated in Cayenne 4.1 and 4.2 was deleted, please review your code before upgrading.
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 1659ea8d4..ebffd4434 100644
--- a/cayenne/src/main/java/org/apache/cayenne/query/SelectById.java
+++ b/cayenne/src/main/java/org/apache/cayenne/query/SelectById.java
@@ -31,6 +31,7 @@ import org.apache.cayenne.map.ObjEntity;
 
 import java.io.Serializable;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.List;
 import java.util.Map;
@@ -55,28 +56,141 @@ public class SelectById<T> extends IndirectQuery implements Select<T> {
 	String cacheGroup;
 	PrefetchTreeNode prefetches;
 
-	public static <T> SelectById<T> query(Class<T> entityType, Object id) {
+	/* Object query factory methods */
+
+	/**
+	 * @since 5.0
+	 */
+	public static <T> SelectById<T> queryId(Class<T> entityType, Object id) {
 		QueryRoot root = new ByEntityTypeResolver(entityType);
 		IdSpec idSpec = new SingleScalarIdSpec(id);
 		return new SelectById<>(root, idSpec);
 	}
 
-	public static <T> SelectById<T> query(Class<T> entityType, Map<String, ?> id) {
+	/**
+	 * @since 5.0
+	 */
+	public static <T> SelectById<T> queryMap(Class<T> entityType, Map<String, ?> id) {
 		QueryRoot root = new ByEntityTypeResolver(entityType);
 		IdSpec idSpec = new SingleMapIdSpec(id);
 		return new SelectById<>(root, idSpec);
 	}
 
-	public static <T> SelectById<T> query(Class<T> entityType, ObjectId id) {
+	/**
+	 * @since 5.0
+	 */
+	public static <T> SelectById<T> queryObjectId(Class<T> entityType, ObjectId id) {
 		checkObjectId(id);
 		QueryRoot root = new ByEntityNameResolver(id.getEntityName());
 		IdSpec idSpec = new SingleMapIdSpec(id.getIdSnapshot());
 		return new SelectById<>(root, idSpec);
 	}
 
+	/**
+	 * @since 5.0
+	 */
+	public static <T> SelectById<T> queryIds(Class<T> entityType, Object... ids) {
+		QueryRoot root = new ByEntityTypeResolver(entityType);
+		IdSpec idSpec = new MultiScalarIdSpec(Arrays.asList(ids));
+		return new SelectById<>(root, idSpec);
+	}
+
+	/**
+	 * @since 5.0
+	 */
+	public static <T> SelectById<T> queryIdsCollection(Class<T> entityType, Collection<Object> ids) {
+		QueryRoot root = new ByEntityTypeResolver(entityType);
+		IdSpec idSpec = new MultiScalarIdSpec(ids);
+		return new SelectById<>(root, idSpec);
+	}
+
+	/**
+	 * @since 5.0
+	 */
+	@SafeVarargs
+	public static <T> SelectById<T> queryMaps(Class<T> entityType, Map<String, ?>... ids) {
+		QueryRoot root = new ByEntityTypeResolver(entityType);
+		IdSpec idSpec = MultiMapIdSpec.ofMap(ids);
+		return new SelectById<>(root, idSpec);
+	}
+
+	/**
+	 * @since 5.0
+	 */
+	public static <T> SelectById<T> queryMapsCollection(Class<T> entityType, Collection<Map<String, ?>> ids) {
+		QueryRoot root = new ByEntityTypeResolver(entityType);
+		IdSpec idSpec = MultiMapIdSpec.ofMapCollection(ids);
+		return new SelectById<>(root, idSpec);
+	}
+
+	/**
+	 * @since 5.0
+	 */
+	public static <T> SelectById<T> queryObjectIds(Class<T> entityType, ObjectId... ids) {
+		if(ids == null || ids.length == 0) {
+			throw new CayenneRuntimeException("Null or empty ids");
+		}
+		String entityName = ids[0].getEntityName();
+		for(ObjectId id : ids) {
+			checkObjectId(id, entityName);
+		}
+
+		QueryRoot root = new ByEntityNameResolver(entityName);
+		IdSpec idSpec = MultiMapIdSpec.ofObjectId(ids);
+		return new SelectById<>(root, idSpec);
+	}
+
+	/**
+	 * @since 5.0
+	 */
+	public static <T> SelectById<T> queryObjectIdsCollection(Class<T> entityType, Collection<ObjectId> ids) {
+		if(ids == null || ids.isEmpty()) {
+			throw new CayenneRuntimeException("Null or empty ids");
+		}
+		String entityName = ids.iterator().next().getEntityName();
+		for(ObjectId id : ids) {
+			checkObjectId(id, entityName);
+		}
+
+		QueryRoot root = new ByEntityNameResolver(entityName);
+		IdSpec idSpec = MultiMapIdSpec.ofObjectIdCollection(ids);
+		return new SelectById<>(root, idSpec);
+	}
+
+	/* Deprecated since 5.0 factory methods */
+
 	/**
 	 * @since 4.2
+	 * @deprecated since 5.0, use {@link #queryId(Class, Object)}
 	 */
+	@Deprecated(since = "5.0", forRemoval = true)
+	public static <T> SelectById<T> query(Class<T> entityType, Object id) {
+		return queryId(entityType, id);
+	}
+
+	/**
+	 * @since 4.2
+	 * @deprecated since 5.0, use {@link #queryMap(Class, Map)}
+	 */
+	@Deprecated(since = "5.0", forRemoval = true)
+	public static <T> SelectById<T> query(Class<T> entityType, Map<String, ?> id) {
+		return queryMap(entityType, id);
+	}
+
+	/**
+	 * @since 4.2
+	 * @deprecated since 5.0, use {@link #queryObjectId(Class, ObjectId)}
+	 */
+	@Deprecated(since = "5.0", forRemoval = true)
+	public static <T> SelectById<T> query(Class<T> entityType, ObjectId id) {
+		return queryObjectId(entityType, id);
+	}
+
+	/**
+	 * @since 4.2
+	 * @deprecated since 5.0, use {@link #queryIds(Class, Object...)}
+	 */
+	@Deprecated(since = "5.0", forRemoval = true)
 	public static <T> SelectById<T> query(Class<T> entityType, Object firstId, Object... otherIds) {
 		QueryRoot root = new ByEntityTypeResolver(entityType);
 		IdSpec idSpec = new MultiScalarIdSpec(firstId, otherIds);
@@ -85,7 +199,9 @@ public class SelectById<T> extends IndirectQuery implements Select<T> {
 
 	/**
 	 * @since 4.2
+	 * @deprecated since 5.0, use {@link #queryIdsCollection(Class, Collection)}
 	 */
+	@Deprecated(since = "5.0", forRemoval = true)
 	public static <T> SelectById<T> query(Class<T> entityType, Collection<Object> ids) {
 		QueryRoot root = new ByEntityTypeResolver(entityType);
 		IdSpec idSpec = new MultiScalarIdSpec(ids);
@@ -94,17 +210,21 @@ public class SelectById<T> extends IndirectQuery implements Select<T> {
 
 	/**
 	 * @since 4.2
+	 * @deprecated since 5.0, use {@link #queryMaps(Class, Map[])}
 	 */
+	@Deprecated(since = "5.0", forRemoval = true)
 	@SafeVarargs
 	public static <T> SelectById<T> query(Class<T> entityType, Map<String, ?> firstId, Map<String, ?>... otherIds) {
 		QueryRoot root = new ByEntityTypeResolver(entityType);
-		IdSpec idSpec = new MultiMapIdSpec(firstId, otherIds);
+		IdSpec idSpec = MultiMapIdSpec.ofMap(firstId, otherIds);
 		return new SelectById<>(root, idSpec);
 	}
 
 	/**
 	 * @since 4.2
+	 * @deprecated since 5.0, use {@link #queryObjectIds(Class, ObjectId...)}
 	 */
+	@Deprecated(since = "5.0", forRemoval = true)
 	public static <T> SelectById<T> query(Class<T> entityType, ObjectId firstId, ObjectId... otherIds) {
 		checkObjectId(firstId);
 		for(ObjectId id : otherIds) {
@@ -112,32 +232,143 @@ public class SelectById<T> extends IndirectQuery implements Select<T> {
 		}
 
 		QueryRoot root = new ByEntityNameResolver(firstId.getEntityName());
-		IdSpec idSpec = new MultiMapIdSpec(firstId, otherIds);
+		IdSpec idSpec = MultiMapIdSpec.ofObjectId(firstId, otherIds);
 		return new SelectById<>(root, idSpec);
 	}
 
-	public static SelectById<DataRow> dataRowQuery(Class<?> entityType, Object id) {
+
+	/* DataRow factory methods */
+
+	/**
+	 * @since 5.0
+	 */
+	public static SelectById<DataRow> dataRowQueryId(Class<?> entityType, Object id) {
 		QueryRoot root = new ByEntityTypeResolver(entityType);
 		IdSpec idSpec = new SingleScalarIdSpec(id);
 		return new SelectById<>(root, idSpec, true);
 	}
 
-	public static SelectById<DataRow> dataRowQuery(Class<?> entityType, Map<String, ?> id) {
+	/**
+	 * @since 5.0
+	 */
+	public static SelectById<DataRow> dataRowQueryMap(Class<?> entityType, Map<String, ?> id) {
 		QueryRoot root = new ByEntityTypeResolver(entityType);
 		IdSpec idSpec = new SingleMapIdSpec(id);
 		return new SelectById<>(root, idSpec, true);
 	}
 
-	public static SelectById<DataRow> dataRowQuery(ObjectId id) {
+	/**
+	 * @since 5.0
+	 */
+	public static SelectById<DataRow> dataRowQueryObjectId(ObjectId id) {
 		checkObjectId(id);
 		QueryRoot root = new ByEntityNameResolver(id.getEntityName());
 		IdSpec idSpec = new SingleMapIdSpec(id.getIdSnapshot());
 		return new SelectById<>(root, idSpec, true);
 	}
 
+	/**
+	 * @since 5.0
+	 */
+	public static SelectById<DataRow> dataRowQueryIds(Class<?> entityType, Object... ids) {
+		QueryRoot root = new ByEntityTypeResolver(entityType);
+		IdSpec idSpec = new MultiScalarIdSpec(Arrays.asList(ids));
+		return new SelectById<>(root, idSpec, true);
+	}
+
+	/**
+	 * @since 5.0
+	 */
+	public static SelectById<DataRow> dataRowQueryIdsCollection(Class<?> entityType, Collection<Object> ids) {
+		QueryRoot root = new ByEntityTypeResolver(entityType);
+		IdSpec idSpec = new MultiScalarIdSpec(ids);
+		return new SelectById<>(root, idSpec, true);
+	}
+
+	/**
+	 * @since 5.0
+	 */
+	@SafeVarargs
+	public static SelectById<DataRow> dataRowQueryMaps(Class<?> entityType, Map<String, ?>... ids) {
+		QueryRoot root = new ByEntityTypeResolver(entityType);
+		IdSpec idSpec = MultiMapIdSpec.ofMap(ids);
+		return new SelectById<>(root, idSpec, true);
+	}
+
+	/**
+	 * @since 5.0
+	 */
+	public static SelectById<DataRow> dataRowQueryMapsCollection(Class<?> entityType, Collection<Map<String, ?>> ids) {
+		QueryRoot root = new ByEntityTypeResolver(entityType);
+		IdSpec idSpec = MultiMapIdSpec.ofMapCollection(ids);
+		return new SelectById<>(root, idSpec, true);
+	}
+
+	/**
+	 * @since 5.0
+	 */
+	public static SelectById<DataRow> dataRowQueryObjectIds(ObjectId... ids) {
+		if(ids == null || ids.length == 0) {
+			throw new CayenneRuntimeException("Null or empty ids");
+		}
+		String entityName = ids[0].getEntityName();
+		for(ObjectId id : ids) {
+			checkObjectId(id, entityName);
+		}
+
+		QueryRoot root = new ByEntityNameResolver(entityName);
+		IdSpec idSpec = MultiMapIdSpec.ofObjectId(ids);
+		return new SelectById<>(root, idSpec, true);
+	}
+
+	/**
+	 * @since 5.0
+	 */
+	public static SelectById<DataRow> dataRowQueryObjectIdsCollection(Collection<ObjectId> ids) {
+		if(ids == null || ids.isEmpty()) {
+			throw new CayenneRuntimeException("Null or empty ids");
+		}
+		String entityName = ids.iterator().next().getEntityName();
+		for(ObjectId id : ids) {
+			checkObjectId(id, entityName);
+		}
+
+		QueryRoot root = new ByEntityNameResolver(entityName);
+		IdSpec idSpec = MultiMapIdSpec.ofObjectIdCollection(ids);
+		return new SelectById<>(root, idSpec, true);
+	}
+
+	/* Deprecated since 5.0 DataRow factory methods */
+
+	/**
+	 * @deprecated since 5.0, use {@link #dataRowQueryId(Class, Object)}
+	 */
+	@Deprecated(since = "5.0", forRemoval = true)
+	public static SelectById<DataRow> dataRowQuery(Class<?> entityType, Object id) {
+		return dataRowQueryId(entityType, id);
+	}
+
+	/**
+	 * @deprecated since 5.0, use {@link #dataRowQueryMap(Class, Map)}
+	 */
+	@Deprecated(since = "5.0", forRemoval = true)
+	public static SelectById<DataRow> dataRowQuery(Class<?> entityType, Map<String, ?> id) {
+		return dataRowQueryMap(entityType, id);
+	}
+
+	/**
+	 * @deprecated since 5.0, use {@link #dataRowQueryObjectId(ObjectId)}
+	 */
+	@Deprecated(since = "5.0", forRemoval = true)
+	public static SelectById<DataRow> dataRowQuery(ObjectId id) {
+		return dataRowQueryObjectId(id);
+	}
+
 	/**
 	 * @since 4.2
+	 * @deprecated since 5.0, use {@link #dataRowQueryIds(Class, Object...)}
 	 */
+	@Deprecated(since = "5.0", forRemoval = true)
 	public static SelectById<DataRow> dataRowQuery(Class<?> entityType, Object firstId, Object... otherIds) {
 		QueryRoot root = new ByEntityTypeResolver(entityType);
 		IdSpec idSpec = new MultiScalarIdSpec(firstId, otherIds);
@@ -146,17 +377,21 @@ public class SelectById<T> extends IndirectQuery implements Select<T> {
 
 	/**
 	 * @since 4.2
+	 * @deprecated since 5.0, use {@link #dataRowQueryMaps(Class, Map[])}
 	 */
+	@Deprecated(since = "5.0", forRemoval = true)
 	@SafeVarargs
 	public static SelectById<DataRow> dataRowQuery(Class<?> entityType, Map<String, ?> firstId, Map<String, ?>... otherIds) {
 		QueryRoot root = new ByEntityTypeResolver(entityType);
-		IdSpec idSpec = new MultiMapIdSpec(firstId, otherIds);
+		IdSpec idSpec = MultiMapIdSpec.ofMap(firstId, otherIds);
 		return new SelectById<>(root, idSpec, true);
 	}
 
 	/**
 	 * @since 4.2
+	 * @deprecated since 5.0, use {@link #dataRowQueryObjectIds(ObjectId...)}
 	 */
+	@Deprecated(since = "5.0", forRemoval = true)
 	public static SelectById<DataRow> dataRowQuery(ObjectId firstId, ObjectId... otherIds) {
 		checkObjectId(firstId);
 		for(ObjectId id : otherIds) {
@@ -164,7 +399,7 @@ public class SelectById<T> extends IndirectQuery implements Select<T> {
 		}
 
 		QueryRoot root = new ByEntityNameResolver(firstId.getEntityName());
-		IdSpec idSpec = new MultiMapIdSpec(firstId, otherIds);
+		IdSpec idSpec = MultiMapIdSpec.ofObjectId(firstId, otherIds);
 		return new SelectById<>(root, idSpec, true);
 	}
 
@@ -378,6 +613,23 @@ public class SelectById<T> extends IndirectQuery implements Select<T> {
 		return result;
 	}
 
+	@SafeVarargs
+	private static <E, R> Collection<R> foldArguments(Function<E, R> mapper, E... other) {
+		List<R> result = new ArrayList<>(other.length);
+		for(E next : other) {
+			result.add(mapper.apply(next));
+		}
+		return result;
+	}
+
+	private static <E, R> Collection<R> foldArguments(Function<E, R> mapper, Collection<E> other) {
+		List<R> result = new ArrayList<>(other.size());
+		for(E next : other) {
+			result.add(mapper.apply(next));
+		}
+		return result;
+	}
+
 	protected interface QueryRoot extends Serializable {
 		ObjEntity resolve(EntityResolver resolver);
 	}
@@ -437,12 +689,33 @@ public class SelectById<T> extends IndirectQuery implements Select<T> {
 		private final Collection<Map<String, ?>> ids;
 
 		@SafeVarargs
-		protected MultiMapIdSpec(Map<String, ?> firstId, Map<String, ?>... otherIds) {
-			this.ids = foldArguments(Function.identity(), firstId, otherIds);
+        static MultiMapIdSpec ofMap(Map<String, ?> firstId, Map<String, ?>... otherIds) {
+			return new MultiMapIdSpec(foldArguments(Function.identity(), firstId, otherIds));
+		}
+
+		@SafeVarargs
+		static MultiMapIdSpec ofMap(Map<String, ?>... ids) {
+			return new MultiMapIdSpec(foldArguments(Function.identity(), ids));
+		}
+
+		static MultiMapIdSpec ofObjectId(ObjectId firstId, ObjectId... otherIds) {
+			return new MultiMapIdSpec(foldArguments(ObjectId::getIdSnapshot, firstId, otherIds));
+		}
+
+		static MultiMapIdSpec ofObjectId(ObjectId... ids) {
+			return new MultiMapIdSpec(foldArguments(ObjectId::getIdSnapshot, ids));
 		}
 
-		protected MultiMapIdSpec(ObjectId firstId, ObjectId... otherIds) {
-			this.ids = foldArguments(ObjectId::getIdSnapshot, firstId, otherIds);
+		static MultiMapIdSpec ofObjectIdCollection(Collection<ObjectId> ids) {
+			return new MultiMapIdSpec(foldArguments(ObjectId::getIdSnapshot, ids));
+		}
+
+		static MultiMapIdSpec ofMapCollection(Collection<Map<String, ?>> ids) {
+			return new MultiMapIdSpec(ids);
+		}
+
+		protected MultiMapIdSpec(Collection<Map<String, ?>> ids) {
+			this.ids = ids;
 		}
 
 		@Override
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 9d491d3b7..77ee93f5c 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
@@ -79,11 +79,11 @@ public class SelectById_RunIT extends RuntimeCase {
 	public void testIntPk() throws Exception {
 		createTwoArtists();
 
-		Artist a3 = SelectById.query(Artist.class, 3).selectOne(context);
+		Artist a3 = SelectById.queryId(Artist.class, 3).selectOne(context);
 		assertNotNull(a3);
 		assertEquals("artist3", a3.getArtistName());
 
-		Artist a2 = SelectById.query(Artist.class, 2).selectOne(context);
+		Artist a2 = SelectById.queryId(Artist.class, 2).selectOne(context);
 		assertNotNull(a2);
 		assertEquals("artist2", a2.getArtistName());
 	}
@@ -92,7 +92,7 @@ public class SelectById_RunIT extends RuntimeCase {
 	public void testIntPkMulti() throws Exception {
 		createTwoArtists();
 
-		List<Artist> artists = SelectById.query(Artist.class, 2, 3)
+		List<Artist> artists = SelectById.queryIds(Artist.class, 2, 3)
 				.select(context);
 		assertEquals(2, artists.size());
 		assertThat(artists.get(0), instanceOf(Artist.class));
@@ -102,46 +102,46 @@ public class SelectById_RunIT extends RuntimeCase {
 	public void testIntPkCollection() throws Exception {
 		createTwoArtists();
 
-		List<Artist> artists = SelectById.query(Artist.class, Arrays.asList(1, 2, 3, 4, 5))
+		List<Artist> artists = SelectById.queryIdsCollection(Artist.class, Arrays.asList(1, 2, 3, 4, 5))
 				.select(context);
 		assertEquals(2, artists.size());
 		assertThat(artists.get(0), instanceOf(Artist.class));
 	}
 
 	@Test
-	public void testIntPk_SelectFirst() throws Exception {
+	public void testMapPk() throws Exception {
 		createTwoArtists();
 
-		Artist a3 = SelectById.query(Artist.class, 3).selectFirst(context);
+		Artist a3 = SelectById.queryMap(Artist.class, singletonMap(Artist.ARTIST_ID_PK_COLUMN, 3)).selectOne(context);
 		assertNotNull(a3);
 		assertEquals("artist3", a3.getArtistName());
 
-		Artist a2 = SelectById.query(Artist.class, 2).selectFirst(context);
+		Artist a2 = SelectById.queryMap(Artist.class, singletonMap(Artist.ARTIST_ID_PK_COLUMN, 2)).selectOne(context);
 		assertNotNull(a2);
 		assertEquals("artist2", a2.getArtistName());
 	}
 
 	@Test
-	public void testMapPk() throws Exception {
+	public void testMapPkMulti() throws Exception {
 		createTwoArtists();
 
-		Artist a3 = SelectById.query(Artist.class, singletonMap(Artist.ARTIST_ID_PK_COLUMN, 3)).selectOne(context);
-		assertNotNull(a3);
-		assertEquals("artist3", a3.getArtistName());
+		Map<String, ?> id2 = Collections.singletonMap(Artist.ARTIST_ID_PK_COLUMN, 2);
+		Map<String, ?> id3 = Collections.singletonMap(Artist.ARTIST_ID_PK_COLUMN, 3);
 
-		Artist a2 = SelectById.query(Artist.class, singletonMap(Artist.ARTIST_ID_PK_COLUMN, 2)).selectOne(context);
-		assertNotNull(a2);
-		assertEquals("artist2", a2.getArtistName());
+		List<Artist> artists = SelectById.queryMaps(Artist.class, id2, id3)
+				.select(context);
+		assertEquals(2, artists.size());
+		assertThat(artists.get(0), instanceOf(Artist.class));
 	}
 
 	@Test
-	public void testMapPkMulti() throws Exception {
+	public void testMapPkCollection() throws Exception {
 		createTwoArtists();
 
 		Map<String, ?> id2 = Collections.singletonMap(Artist.ARTIST_ID_PK_COLUMN, 2);
 		Map<String, ?> id3 = Collections.singletonMap(Artist.ARTIST_ID_PK_COLUMN, 3);
 
-		List<Artist> artists = SelectById.query(Artist.class, id2, id3)
+		List<Artist> artists = SelectById.queryMapsCollection(Artist.class, Arrays.asList(id2, id3))
 				.select(context);
 		assertEquals(2, artists.size());
 		assertThat(artists.get(0), instanceOf(Artist.class));
@@ -152,12 +152,12 @@ public class SelectById_RunIT extends RuntimeCase {
 		createTwoArtists();
 
 		ObjectId oid3 = ObjectId.of("Artist", Artist.ARTIST_ID_PK_COLUMN, 3);
-		Artist a3 = SelectById.query(Artist.class, oid3).selectOne(context);
+		Artist a3 = SelectById.queryObjectId(Artist.class, oid3).selectOne(context);
 		assertNotNull(a3);
 		assertEquals("artist3", a3.getArtistName());
 
 		ObjectId oid2 = ObjectId.of("Artist", Artist.ARTIST_ID_PK_COLUMN, 2);
-		Artist a2 = SelectById.query(Artist.class, oid2).selectOne(context);
+		Artist a2 = SelectById.queryObjectId(Artist.class, oid2).selectOne(context);
 		assertNotNull(a2);
 		assertEquals("artist2", a2.getArtistName());
 	}
@@ -169,7 +169,20 @@ public class SelectById_RunIT extends RuntimeCase {
 		ObjectId oid2 = ObjectId.of("Artist", Artist.ARTIST_ID_PK_COLUMN, 2);
 		ObjectId oid3 = ObjectId.of("Artist", Artist.ARTIST_ID_PK_COLUMN, 3);
 
-		List<Artist> artists = SelectById.query(Artist.class, oid2, oid3)
+		List<Artist> artists = SelectById.queryObjectIds(Artist.class, oid2, oid3)
+				.select(context);
+		assertEquals(2, artists.size());
+		assertThat(artists.get(0), instanceOf(Artist.class));
+	}
+
+	@Test
+	public void testObjectIdPkCollection() throws Exception {
+		createTwoArtists();
+
+		ObjectId oid2 = ObjectId.of("Artist", Artist.ARTIST_ID_PK_COLUMN, 2);
+		ObjectId oid3 = ObjectId.of("Artist", Artist.ARTIST_ID_PK_COLUMN, 3);
+
+		List<Artist> artists = SelectById.queryObjectIdsCollection(Artist.class, Arrays.asList(oid2, oid3))
 				.select(context);
 		assertEquals(2, artists.size());
 		assertThat(artists.get(0), instanceOf(Artist.class));
@@ -179,11 +192,11 @@ public class SelectById_RunIT extends RuntimeCase {
 	public void testDataRowIntPk() throws Exception {
 		createTwoArtists();
 
-		DataRow a3 = SelectById.dataRowQuery(Artist.class, 3).selectOne(context);
+		DataRow a3 = SelectById.dataRowQueryId(Artist.class, 3).selectOne(context);
 		assertNotNull(a3);
 		assertEquals("artist3", a3.get("ARTIST_NAME"));
 
-		DataRow a2 = SelectById.dataRowQuery(Artist.class, 2).selectOne(context);
+		DataRow a2 = SelectById.dataRowQueryId(Artist.class, 2).selectOne(context);
 		assertNotNull(a2);
 		assertEquals("artist2", a2.get("ARTIST_NAME"));
 	}
@@ -193,12 +206,12 @@ public class SelectById_RunIT extends RuntimeCase {
 		createTwoArtists();
 
 		Map<String, ?> id3 = Collections.singletonMap(Artist.ARTIST_ID_PK_COLUMN, 3);
-		DataRow a3 = SelectById.dataRowQuery(Artist.class, id3).selectOne(context);
+		DataRow a3 = SelectById.dataRowQueryMap(Artist.class, id3).selectOne(context);
 		assertNotNull(a3);
 		assertEquals("artist3", a3.get("ARTIST_NAME"));
 
 		Map<String, ?> id2 = Collections.singletonMap(Artist.ARTIST_ID_PK_COLUMN, 2);
-		DataRow a2 = SelectById.dataRowQuery(Artist.class, id2).selectOne(context);
+		DataRow a2 = SelectById.dataRowQueryMap(Artist.class, id2).selectOne(context);
 		assertNotNull(a2);
 		assertEquals("artist2", a2.get("ARTIST_NAME"));
 	}
@@ -208,12 +221,12 @@ public class SelectById_RunIT extends RuntimeCase {
 		createTwoArtists();
 
 		ObjectId oid3 = ObjectId.of("Artist", Artist.ARTIST_ID_PK_COLUMN, 3);
-		DataRow a3 = SelectById.dataRowQuery(oid3).selectOne(context);
+		DataRow a3 = SelectById.dataRowQueryObjectId(oid3).selectOne(context);
 		assertNotNull(a3);
 		assertEquals("artist3", a3.get("ARTIST_NAME"));
 
 		ObjectId oid2 = ObjectId.of("Artist", Artist.ARTIST_ID_PK_COLUMN, 2);
-		DataRow a2 = SelectById.dataRowQuery(oid2).selectOne(context);
+		DataRow a2 = SelectById.dataRowQueryObjectId(oid2).selectOne(context);
 		assertNotNull(a2);
 		assertEquals("artist2", a2.get("ARTIST_NAME"));
 	}
@@ -222,7 +235,20 @@ public class SelectById_RunIT extends RuntimeCase {
 	public void testDataRowIntPkMulti() throws Exception {
 		createTwoArtists();
 
-		List<DataRow> artists = SelectById.dataRowQuery(Artist.class, 2, 3)
+		List<DataRow> artists = SelectById.dataRowQueryIds(Artist.class, 2, 3)
+				.select(context);
+		assertEquals(2, artists.size());
+		assertThat(artists.get(0), instanceOf(DataRow.class));
+	}
+
+	@Test
+	public void testDataRowObjectIdPkMulti() throws Exception {
+		createTwoArtists();
+
+		ObjectId oid2 = ObjectId.of("Artist", Artist.ARTIST_ID_PK_COLUMN, 2);
+		ObjectId oid3 = ObjectId.of("Artist", Artist.ARTIST_ID_PK_COLUMN, 3);
+
+		List<DataRow> artists = SelectById.dataRowQueryObjectIds(oid2, oid3)
 				.select(context);
 		assertEquals(2, artists.size());
 		assertThat(artists.get(0), instanceOf(DataRow.class));
@@ -232,37 +258,72 @@ public class SelectById_RunIT extends RuntimeCase {
 	public void testDataRowMapPkMulti() throws Exception {
 		createTwoArtists();
 
+		Map<String, ?> id2 = Collections.singletonMap(Artist.ARTIST_ID_PK_COLUMN, 2);
+		Map<String, ?> id3 = Collections.singletonMap(Artist.ARTIST_ID_PK_COLUMN, 3);
+
+		List<DataRow> artists = SelectById.dataRowQueryMaps(Artist.class, id2, id3)
+				.select(context);
+		assertEquals(2, artists.size());
+		assertThat(artists.get(0), instanceOf(DataRow.class));
+	}
+
+	@Test
+	public void testDataRowIntPkCollection() throws Exception {
+		createTwoArtists();
+
+		List<DataRow> artists = SelectById.dataRowQueryIdsCollection(Artist.class, Arrays.asList(2, 3))
+				.select(context);
+		assertEquals(2, artists.size());
+		assertThat(artists.get(0), instanceOf(DataRow.class));
+	}
+
+	@Test
+	public void testDataRowObjectIdPkCollection() throws Exception {
+		createTwoArtists();
+
 		ObjectId oid2 = ObjectId.of("Artist", Artist.ARTIST_ID_PK_COLUMN, 2);
 		ObjectId oid3 = ObjectId.of("Artist", Artist.ARTIST_ID_PK_COLUMN, 3);
 
-		List<DataRow> artists = SelectById.dataRowQuery(oid2, oid3)
+		List<DataRow> artists = SelectById.dataRowQueryObjectIdsCollection(Arrays.asList(oid2, oid3))
 				.select(context);
 		assertEquals(2, artists.size());
 		assertThat(artists.get(0), instanceOf(DataRow.class));
 	}
 
 	@Test
-	public void testDataRowObjectIdPkMulti() throws Exception {
+	public void testDataRowMapPkCollection() throws Exception {
 		createTwoArtists();
 
 		Map<String, ?> id2 = Collections.singletonMap(Artist.ARTIST_ID_PK_COLUMN, 2);
 		Map<String, ?> id3 = Collections.singletonMap(Artist.ARTIST_ID_PK_COLUMN, 3);
 
-		List<DataRow> artists = SelectById.dataRowQuery(Artist.class, id2, id3)
+		List<DataRow> artists = SelectById.dataRowQueryMapsCollection(Artist.class, Arrays.asList(id2, id3))
 				.select(context);
 		assertEquals(2, artists.size());
 		assertThat(artists.get(0), instanceOf(DataRow.class));
 	}
 
+	@Test
+	public void testIntPk_SelectFirst() throws Exception {
+		createTwoArtists();
+
+		Artist a3 = SelectById.queryId(Artist.class, 3).selectFirst(context);
+		assertNotNull(a3);
+		assertEquals("artist3", a3.getArtistName());
+
+		Artist a2 = SelectById.queryId(Artist.class, 2).selectFirst(context);
+		assertNotNull(a2);
+		assertEquals("artist2", a2.getArtistName());
+	}
 
 	@Test
-	public void testMetadataCacheKey() throws Exception {
-		SelectById<Painting> q1 = SelectById.query(Painting.class, 4).localCache();
+	public void testMetadataCacheKey() {
+		SelectById<Painting> q1 = SelectById.queryId(Painting.class, 4).localCache();
 		QueryMetadata md1 = q1.getMetaData(resolver);
 		assertNotNull(md1);
 		assertNotNull(md1.getCacheKey());
 
-		SelectById<Painting> q2 = SelectById.query(Painting.class, singletonMap(Painting.PAINTING_ID_PK_COLUMN, 4))
+		SelectById<Painting> q2 = SelectById.queryId(Painting.class, singletonMap(Painting.PAINTING_ID_PK_COLUMN, 4))
 				.localCache();
 		QueryMetadata md2 = q2.getMetaData(resolver);
 		assertNotNull(md2);
@@ -272,20 +333,20 @@ public class SelectById_RunIT extends RuntimeCase {
 		// cache entry
 		assertEquals(md1.getCacheKey(), md2.getCacheKey());
 
-		SelectById<Painting> q3 = SelectById.query(Painting.class, 5).localCache();
+		SelectById<Painting> q3 = SelectById.queryId(Painting.class, 5).localCache();
 		QueryMetadata md3 = q3.getMetaData(resolver);
 		assertNotNull(md3);
 		assertNotNull(md3.getCacheKey());
 		assertNotEquals(md1.getCacheKey(), md3.getCacheKey());
 
-		SelectById<Artist> q4 = SelectById.query(Artist.class, 4).localCache();
+		SelectById<Artist> q4 = SelectById.queryId(Artist.class, 4).localCache();
 		QueryMetadata md4 = q4.getMetaData(resolver);
 		assertNotNull(md4);
 		assertNotNull(md4.getCacheKey());
 		assertNotEquals(md1.getCacheKey(), md4.getCacheKey());
 
 		SelectById<Painting> q5 = SelectById
-				.query(Painting.class, ObjectId.of("Painting", Painting.PAINTING_ID_PK_COLUMN, 4))
+				.queryId(Painting.class, ObjectId.of("Painting", Painting.PAINTING_ID_PK_COLUMN, 4))
 				.localCache();
 		QueryMetadata md5 = q5.getMetaData(resolver);
 		assertNotNull(md5);
@@ -302,20 +363,20 @@ public class SelectById_RunIT extends RuntimeCase {
 		final Artist[] a3 = new Artist[1];
 
 		assertEquals(1, interceptor.runWithQueryCounter(() -> {
-			a3[0] = SelectById.query(Artist.class, 3).localCache("g1").selectOne(context);
+			a3[0] = SelectById.queryId(Artist.class, 3).localCache("g1").selectOne(context);
 			assertNotNull(a3[0]);
 			assertEquals("artist3", a3[0].getArtistName());
 		}));
 
 		interceptor.runWithQueriesBlocked(() -> {
-			Artist a3cached = SelectById.query(Artist.class, 3).localCache("g1").selectOne(context);
+			Artist a3cached = SelectById.queryId(Artist.class, 3).localCache("g1").selectOne(context);
 			assertSame(a3[0], a3cached);
 		});
 
 		context.performGenericQuery(new RefreshQuery("g1"));
 
 		assertEquals(1, interceptor.runWithQueryCounter(() ->
-				SelectById.query(Artist.class, 3).localCache("g1").selectOne(context)));
+				SelectById.queryId(Artist.class, 3).localCache("g1").selectOne(context)));
 	}
 
 	@Test
@@ -324,7 +385,7 @@ public class SelectById_RunIT extends RuntimeCase {
 		tPainting.insert(45, 3, "One");
 		tPainting.insert(48, 3, "Two");
 
-		final Artist a3 = SelectById.query(Artist.class, 3)
+		final Artist a3 = SelectById.queryId(Artist.class, 3)
 				.prefetch(Artist.PAINTING_ARRAY.joint())
 				.selectOne(context);
 
@@ -337,4 +398,185 @@ public class SelectById_RunIT extends RuntimeCase {
 			a3.getPaintingArray().get(1).getPaintingTitle();
 		});
 	}
+
+	/* deprecated methods tests */
+
+	@SuppressWarnings("removal")
+	@Test
+	public void testIntPkDeprecated() throws Exception {
+		createTwoArtists();
+
+		Artist a3 = SelectById.query(Artist.class, 3).selectOne(context);
+		assertNotNull(a3);
+		assertEquals("artist3", a3.getArtistName());
+
+		Artist a2 = SelectById.query(Artist.class, 2).selectOne(context);
+		assertNotNull(a2);
+		assertEquals("artist2", a2.getArtistName());
+	}
+
+	@SuppressWarnings("removal")
+    @Test
+	public void testIntPkMultiDeprecated() throws Exception {
+		createTwoArtists();
+
+		List<Artist> artists = SelectById.query(Artist.class, 2, 3)
+				.select(context);
+		assertEquals(2, artists.size());
+		assertThat(artists.get(0), instanceOf(Artist.class));
+	}
+
+	@SuppressWarnings("removal")
+    @Test
+	public void testIntPkCollectionDeprecation() throws Exception {
+		createTwoArtists();
+
+		List<Artist> artists = SelectById.query(Artist.class, Arrays.asList(1, 2, 3, 4, 5))
+				.select(context);
+		assertEquals(2, artists.size());
+		assertThat(artists.get(0), instanceOf(Artist.class));
+	}
+
+	@SuppressWarnings("removal")
+	@Test
+	public void testMapPkDeprecation() throws Exception {
+		createTwoArtists();
+
+		Artist a3 = SelectById.query(Artist.class, singletonMap(Artist.ARTIST_ID_PK_COLUMN, 3)).selectOne(context);
+		assertNotNull(a3);
+		assertEquals("artist3", a3.getArtistName());
+
+		Artist a2 = SelectById.query(Artist.class, singletonMap(Artist.ARTIST_ID_PK_COLUMN, 2)).selectOne(context);
+		assertNotNull(a2);
+		assertEquals("artist2", a2.getArtistName());
+	}
+
+	@SuppressWarnings("removal")
+	@Test
+	public void testMapPkMultiDeprecation() throws Exception {
+		createTwoArtists();
+
+		Map<String, ?> id2 = Collections.singletonMap(Artist.ARTIST_ID_PK_COLUMN, 2);
+		Map<String, ?> id3 = Collections.singletonMap(Artist.ARTIST_ID_PK_COLUMN, 3);
+
+		List<Artist> artists = SelectById.query(Artist.class, id2, id3)
+				.select(context);
+		assertEquals(2, artists.size());
+		assertThat(artists.get(0), instanceOf(Artist.class));
+	}
+
+	@SuppressWarnings("removal")
+	@Test
+	public void testObjectIdPkDeprecation() throws Exception {
+		createTwoArtists();
+
+		ObjectId oid3 = ObjectId.of("Artist", Artist.ARTIST_ID_PK_COLUMN, 3);
+		Artist a3 = SelectById.query(Artist.class, oid3).selectOne(context);
+		assertNotNull(a3);
+		assertEquals("artist3", a3.getArtistName());
+
+		ObjectId oid2 = ObjectId.of("Artist", Artist.ARTIST_ID_PK_COLUMN, 2);
+		Artist a2 = SelectById.query(Artist.class, oid2).selectOne(context);
+		assertNotNull(a2);
+		assertEquals("artist2", a2.getArtistName());
+	}
+
+	@SuppressWarnings("removal")
+	@Test
+	public void testObjectIdPkMultiDeprecation() throws Exception {
+		createTwoArtists();
+
+		ObjectId oid2 = ObjectId.of("Artist", Artist.ARTIST_ID_PK_COLUMN, 2);
+		ObjectId oid3 = ObjectId.of("Artist", Artist.ARTIST_ID_PK_COLUMN, 3);
+
+		List<Artist> artists = SelectById.query(Artist.class, oid2, oid3)
+				.select(context);
+		assertEquals(2, artists.size());
+		assertThat(artists.get(0), instanceOf(Artist.class));
+	}
+
+	@SuppressWarnings("removal")
+	@Test
+	public void testDataRowIntPkDeprecation() throws Exception {
+		createTwoArtists();
+
+		DataRow a3 = SelectById.dataRowQuery(Artist.class, 3).selectOne(context);
+		assertNotNull(a3);
+		assertEquals("artist3", a3.get("ARTIST_NAME"));
+
+		DataRow a2 = SelectById.dataRowQuery(Artist.class, 2).selectOne(context);
+		assertNotNull(a2);
+		assertEquals("artist2", a2.get("ARTIST_NAME"));
+	}
+
+	@SuppressWarnings("removal")
+	@Test
+	public void testDataRowMapPkDeprecation() throws Exception {
+		createTwoArtists();
+
+		Map<String, ?> id3 = Collections.singletonMap(Artist.ARTIST_ID_PK_COLUMN, 3);
+		DataRow a3 = SelectById.dataRowQuery(Artist.class, id3).selectOne(context);
+		assertNotNull(a3);
+		assertEquals("artist3", a3.get("ARTIST_NAME"));
+
+		Map<String, ?> id2 = Collections.singletonMap(Artist.ARTIST_ID_PK_COLUMN, 2);
+		DataRow a2 = SelectById.dataRowQuery(Artist.class, id2).selectOne(context);
+		assertNotNull(a2);
+		assertEquals("artist2", a2.get("ARTIST_NAME"));
+	}
+
+	@SuppressWarnings("removal")
+	@Test
+	public void testDataRowObjectIdPkDeprecation() throws Exception {
+		createTwoArtists();
+
+		ObjectId oid3 = ObjectId.of("Artist", Artist.ARTIST_ID_PK_COLUMN, 3);
+		DataRow a3 = SelectById.dataRowQuery(oid3).selectOne(context);
+		assertNotNull(a3);
+		assertEquals("artist3", a3.get("ARTIST_NAME"));
+
+		ObjectId oid2 = ObjectId.of("Artist", Artist.ARTIST_ID_PK_COLUMN, 2);
+		DataRow a2 = SelectById.dataRowQuery(oid2).selectOne(context);
+		assertNotNull(a2);
+		assertEquals("artist2", a2.get("ARTIST_NAME"));
+	}
+
+	@SuppressWarnings("removal")
+	@Test
+	public void testDataRowIntPkMultiDeprecation() throws Exception {
+		createTwoArtists();
+
+		List<DataRow> artists = SelectById.dataRowQuery(Artist.class, 2, 3)
+				.select(context);
+		assertEquals(2, artists.size());
+		assertThat(artists.get(0), instanceOf(DataRow.class));
+	}
+
+	@SuppressWarnings("removal")
+	@Test
+	public void testDataRowMapPkMultiDeprecation() throws Exception {
+		createTwoArtists();
+
+		ObjectId oid2 = ObjectId.of("Artist", Artist.ARTIST_ID_PK_COLUMN, 2);
+		ObjectId oid3 = ObjectId.of("Artist", Artist.ARTIST_ID_PK_COLUMN, 3);
+
+		List<DataRow> artists = SelectById.dataRowQuery(oid2, oid3)
+				.select(context);
+		assertEquals(2, artists.size());
+		assertThat(artists.get(0), instanceOf(DataRow.class));
+	}
+
+	@SuppressWarnings("removal")
+	@Test
+	public void testDataRowObjectIdPkMultiDeprecation() throws Exception {
+		createTwoArtists();
+
+		Map<String, ?> id2 = Collections.singletonMap(Artist.ARTIST_ID_PK_COLUMN, 2);
+		Map<String, ?> id3 = Collections.singletonMap(Artist.ARTIST_ID_PK_COLUMN, 3);
+
+		List<DataRow> artists = SelectById.dataRowQuery(Artist.class, id2, id3)
+				.select(context);
+		assertEquals(2, artists.size());
+		assertThat(artists.get(0), instanceOf(DataRow.class));
+	}
 }