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 e76287c CAY-2651 Support multiple IDs in the SelectById query e76287c is described below commit e76287c9fb22a06e0bbb0062e0464bc60fa5fdc6 Author: Nikita Timofeev <stari...@gmail.com> AuthorDate: Wed Mar 11 16:07:29 2020 +0300 CAY-2651 Support multiple IDs in the SelectById query --- RELEASE-NOTES.txt | 1 + .../{SelectByIdTest.java => SelectById_IT.java} | 19 +- .../java/org/apache/cayenne/query/SelectById.java | 272 +++++++++++++++------ .../org/apache/cayenne/query/SelectById_RunIT.java | 187 ++++++++++---- 4 files changed, 360 insertions(+), 119 deletions(-) diff --git a/RELEASE-NOTES.txt b/RELEASE-NOTES.txt index fa40183..5827792 100644 --- a/RELEASE-NOTES.txt +++ b/RELEASE-NOTES.txt @@ -56,6 +56,7 @@ CAY-2611 Exclude system catalogs and schemas when run dbImport without config CAY-2612 Modeler: add lazy-loading to dbImport tab CAY-2645 Modeler: DbImport tree highlight improvement CAY-2650 Support using generated primary keys along with batch inserts +CAY-2651 Support multiple IDs in the SelectById query Bug Fixes: diff --git a/cayenne-client/src/test/java/org/apache/cayenne/query/SelectByIdTest.java b/cayenne-client/src/test/java/org/apache/cayenne/query/SelectById_IT.java similarity index 70% rename from cayenne-client/src/test/java/org/apache/cayenne/query/SelectByIdTest.java rename to cayenne-client/src/test/java/org/apache/cayenne/query/SelectById_IT.java index 6f44f70..2589203 100644 --- a/cayenne-client/src/test/java/org/apache/cayenne/query/SelectByIdTest.java +++ b/cayenne-client/src/test/java/org/apache/cayenne/query/SelectById_IT.java @@ -22,12 +22,21 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotSame; import static org.junit.Assert.assertTrue; +import org.apache.cayenne.di.Inject; import org.apache.cayenne.map.EntityResolver; +import org.apache.cayenne.map.ObjEntity; import org.apache.cayenne.remote.hessian.service.HessianUtil; import org.apache.cayenne.testdo.testmap.Artist; +import org.apache.cayenne.unit.di.server.CayenneProjects; +import org.apache.cayenne.unit.di.server.ServerCase; +import org.apache.cayenne.unit.di.server.UseServerRuntime; import org.junit.Test; -public class SelectByIdTest { +@UseServerRuntime(CayenneProjects.TESTMAP_PROJECT) +public class SelectById_IT extends ServerCase { + + @Inject + private EntityResolver resolver; @Test public void testSerializabilityWithHessian() throws Exception { @@ -38,7 +47,11 @@ public class SelectByIdTest { SelectById<?> c1 = (SelectById<?>) clone; assertNotSame(o, c1); - assertEquals(o.entityType, c1.entityType); - assertEquals(o.singleId, c1.singleId); + + ObjEntity artistEntity = resolver.getObjEntity(Artist.class); + + assertEquals(artistEntity, o.root.resolve(resolver)); + assertEquals(o.root.resolve(resolver), c1.root.resolve(resolver)); + assertEquals(o.idSpec.getQualifier(artistEntity), c1.idSpec.getQualifier(artistEntity)); } } diff --git a/cayenne-server/src/main/java/org/apache/cayenne/query/SelectById.java b/cayenne-server/src/main/java/org/apache/cayenne/query/SelectById.java index a15ec2f..949efdb 100644 --- a/cayenne-server/src/main/java/org/apache/cayenne/query/SelectById.java +++ b/cayenne-server/src/main/java/org/apache/cayenne/query/SelectById.java @@ -29,15 +29,17 @@ import org.apache.cayenne.exp.Expression; import org.apache.cayenne.map.EntityResolver; import org.apache.cayenne.map.ObjEntity; +import java.io.Serializable; +import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Map; +import java.util.function.Function; -import static java.util.Collections.singletonMap; -import static org.apache.cayenne.exp.ExpressionFactory.matchAllDbExp; +import static org.apache.cayenne.exp.ExpressionFactory.*; /** - * A query to select single objects by id. + * A query to select objects by id. * * @since 4.0 */ @@ -45,88 +47,135 @@ public class SelectById<T> extends IndirectQuery implements Select<T> { private static final long serialVersionUID = -6589464349051607583L; - // type is not same as T, as T maybe be DataRow or scalar - // either type or entity name is specified, but not both - Class<?> entityType; - String entityName; + final QueryRoot root; + final IdSpec idSpec; + final boolean fetchingDataRows; - // only one of the two id forms is provided, but not both - Object singleId; - Map<String, ?> mapId; - - boolean fetchingDataRows; QueryCacheStrategy cacheStrategy; String cacheGroup; PrefetchTreeNode prefetches; public static <T> SelectById<T> query(Class<T> entityType, Object id) { - SelectById<T> q = new SelectById<>(); - - q.entityType = entityType; - q.singleId = id; - q.fetchingDataRows = false; - - return q; + QueryRoot root = resolver -> resolver.getObjEntity(entityType, true); + IdSpec idSpec = new SingleScalarIdSpec(id); + return new SelectById<>(root, idSpec); } public static <T> SelectById<T> query(Class<T> entityType, Map<String, ?> id) { - SelectById<T> q = new SelectById<>(); - - q.entityType = entityType; - q.mapId = id; - q.fetchingDataRows = false; - - return q; + QueryRoot root = resolver -> resolver.getObjEntity(entityType, true); + IdSpec idSpec = new SingleMapIdSpec(id); + return new SelectById<>(root, idSpec); } public static <T> SelectById<T> query(Class<T> entityType, ObjectId id) { checkObjectId(id); + QueryRoot root = resolver -> resolver.getObjEntity(id.getEntityName()); + IdSpec idSpec = new SingleMapIdSpec(id.getIdSnapshot()); + return new SelectById<>(root, idSpec); + } - SelectById<T> q = new SelectById<>(); - - q.entityName = id.getEntityName(); - q.mapId = id.getIdSnapshot(); - q.fetchingDataRows = false; + /** + * @since 4.2 + */ + public static <T> SelectById<T> query(Class<T> entityType, Object firstId, Object... otherIds) { + QueryRoot root = resolver -> resolver.getObjEntity(entityType, true); + IdSpec idSpec = new MultiScalarIdSpec(firstId, otherIds); + return new SelectById<>(root, idSpec); + } - return q; + /** + * @since 4.2 + */ + public static <T> SelectById<T> query(Class<T> entityType, Collection<Object> ids) { + QueryRoot root = resolver -> resolver.getObjEntity(entityType, true); + IdSpec idSpec = new MultiScalarIdSpec(ids); + return new SelectById<>(root, idSpec); } - public static SelectById<DataRow> dataRowQuery(Class<?> entityType, Object id) { - SelectById<DataRow> q = new SelectById<>(); + /** + * @since 4.2 + */ + @SafeVarargs + public static <T> SelectById<T> query(Class<T> entityType, Map<String, ?> firstId, Map<String, ?>... otherIds) { + QueryRoot root = resolver -> resolver.getObjEntity(entityType, true); + IdSpec idSpec = new MultiMapIdSpec(firstId, otherIds); + return new SelectById<>(root, idSpec); + } - q.entityType = entityType; - q.singleId = id; - q.fetchingDataRows = true; + /** + * @since 4.2 + */ + public static <T> SelectById<T> query(Class<T> entityType, ObjectId firstId, ObjectId... otherIds) { + checkObjectId(firstId); + for(ObjectId id : otherIds) { + checkObjectId(id, firstId.getEntityName()); + } - return q; + QueryRoot root = resolver -> resolver.getObjEntity(firstId.getEntityName()); + IdSpec idSpec = new MultiMapIdSpec(firstId, otherIds); + return new SelectById<>(root, idSpec); } - public static SelectById<DataRow> dataRowQuery(Class<?> entityType, Map<String, Object> id) { - SelectById<DataRow> q = new SelectById<>(); - - q.entityType = entityType; - q.mapId = id; - q.fetchingDataRows = true; + public static SelectById<DataRow> dataRowQuery(Class<?> entityType, Object id) { + QueryRoot root = resolver -> resolver.getObjEntity(entityType, true); + IdSpec idSpec = new SingleScalarIdSpec(id); + return new SelectById<>(root, idSpec, true); + } - return q; + public static SelectById<DataRow> dataRowQuery(Class<?> entityType, Map<String, ?> id) { + QueryRoot root = resolver -> resolver.getObjEntity(entityType, true); + IdSpec idSpec = new SingleMapIdSpec(id); + return new SelectById<>(root, idSpec, true); } public static SelectById<DataRow> dataRowQuery(ObjectId id) { checkObjectId(id); + QueryRoot root = resolver -> resolver.getObjEntity(id.getEntityName()); + IdSpec idSpec = new SingleMapIdSpec(id.getIdSnapshot()); + return new SelectById<>(root, idSpec, true); + } - SelectById<DataRow> q = new SelectById<>(); - - q.entityName = id.getEntityName(); - q.mapId = id.getIdSnapshot(); - q.fetchingDataRows = true; + /** + * @since 4.2 + */ + public static SelectById<DataRow> dataRowQuery(Class<?> entityType, Object firstId, Object... otherIds) { + QueryRoot root = resolver -> resolver.getObjEntity(entityType, true); + IdSpec idSpec = new MultiScalarIdSpec(firstId, otherIds); + return new SelectById<>(root, idSpec, true); + } - return q; + /** + * @since 4.2 + */ + @SafeVarargs + public static SelectById<DataRow> dataRowQuery(Class<?> entityType, Map<String, ?> firstId, Map<String, ?>... otherIds) { + QueryRoot root = resolver -> resolver.getObjEntity(entityType, true); + IdSpec idSpec = new MultiMapIdSpec(firstId, otherIds); + return new SelectById<>(root, idSpec, true); } - private static void checkObjectId(ObjectId id) { - if (id.isTemporary() && !id.isReplacementIdAttached()) { - throw new CayenneRuntimeException("Can't build a query for temporary id: %s", id); + /** + * @since 4.2 + */ + public static SelectById<DataRow> dataRowQuery(ObjectId firstId, ObjectId... otherIds) { + checkObjectId(firstId); + for(ObjectId id : otherIds) { + checkObjectId(id, firstId.getEntityName()); } + + QueryRoot root = resolver -> resolver.getObjEntity(firstId.getEntityName()); + IdSpec idSpec = new MultiMapIdSpec(firstId, otherIds); + return new SelectById<>(root, idSpec, true); + } + + protected SelectById(QueryRoot root, IdSpec idSpec, boolean fetchingDataRows) { + this.root = root; + this.idSpec = idSpec; + this.fetchingDataRows = fetchingDataRows; + } + + protected SelectById(QueryRoot root, IdSpec idSpec) { + this(root, idSpec, false); } @Override @@ -284,14 +333,12 @@ public class SelectById<T> extends IndirectQuery implements Select<T> { @SuppressWarnings("deprecation") @Override protected Query createReplacementQuery(EntityResolver resolver) { - - ObjEntity entity = resolveEntity(resolver); - Map<String, ?> id = resolveId(entity); + ObjEntity entity = root.resolve(resolver); SelectQuery<Object> query = new SelectQuery<>(); query.setRoot(entity); query.setFetchingDataRows(fetchingDataRows); - query.setQualifier(matchAllDbExp(id, Expression.EQUAL_TO)); + query.setQualifier(idSpec.getQualifier(entity)); // note on caching... this hits query cache instead of object cache... // until we merge the two this may result in not using the cache @@ -303,31 +350,112 @@ public class SelectById<T> extends IndirectQuery implements Select<T> { return query; } - protected Map<String, ?> resolveId(ObjEntity entity) { + private static String resolveSinglePkName(ObjEntity entity) { + Collection<String> pkAttributes = entity.getPrimaryKeyNames(); + if(pkAttributes.size() == 1) { + return pkAttributes.iterator().next(); + } + throw new CayenneRuntimeException("PK contains %d columns, expected 1.", pkAttributes.size()); + } - if (singleId == null && mapId == null) { - throw new CayenneRuntimeException("Misconfigured query. Either singleId or mapId must be set"); + private static void checkObjectId(ObjectId id) { + if (id.isTemporary() && !id.isReplacementIdAttached()) { + throw new CayenneRuntimeException("Can't build a query for a temporary id: %s", id); } + } - if (mapId != null) { - return mapId; + private static void checkObjectId(ObjectId id, String entityName) { + checkObjectId(id); + if(!entityName.equals(id.getEntityName())) { + throw new CayenneRuntimeException("Can't build a query with mixed object types for given ObjectIds"); } + } - Collection<String> pkAttributes = entity.getPrimaryKeyNames(); - if (pkAttributes.size() != 1) { - throw new CayenneRuntimeException("PK contains %d columns, expected 1.", pkAttributes.size()); + @SafeVarargs + private static <E, R> Collection<R> foldArguments(Function<E, R> mapper, E first, E... other) { + List<R> result = new ArrayList<>(); + result.add(mapper.apply(first)); + for(E next : other) { + result.add(mapper.apply(next)); + } + return result; + } + + protected interface QueryRoot extends Serializable { + ObjEntity resolve(EntityResolver resolver); + } + + protected interface IdSpec extends Serializable{ + Expression getQualifier(ObjEntity entity); + } + + protected static class SingleScalarIdSpec implements IdSpec { + + private final Object id; + + protected SingleScalarIdSpec(Object id) { + this.id = id; } - String pk = pkAttributes.iterator().next(); - return singletonMap(pk, singleId); + @Override + public Expression getQualifier(ObjEntity entity) { + return matchDbExp(resolveSinglePkName(entity), id); + } } - protected ObjEntity resolveEntity(EntityResolver resolver) { + protected static class MultiScalarIdSpec implements IdSpec { - if (entityName == null && entityType == null) { - throw new CayenneRuntimeException("Misconfigured query. Either entityName or entityType must be set"); + private final Collection<Object> ids; + + protected MultiScalarIdSpec(Object firstId, Object... otherIds) { + this.ids = foldArguments(Function.identity(), firstId, otherIds); } - return entityName != null ? resolver.getObjEntity(entityName) : resolver.getObjEntity(entityType, true); + protected MultiScalarIdSpec(Collection<Object> ids) { + this.ids = ids; + } + + @Override + public Expression getQualifier(ObjEntity entity) { + return inDbExp(resolveSinglePkName(entity), ids); + } + } + + protected static class SingleMapIdSpec implements IdSpec { + + private final Map<String, ?> id; + + protected SingleMapIdSpec(Map<String, ?> id) { + this.id = id; + } + + @Override + public Expression getQualifier(ObjEntity entity) { + return matchAllDbExp(id, Expression.EQUAL_TO); + } + } + + protected static class MultiMapIdSpec implements IdSpec { + + private final Collection<Map<String, ?>> ids; + + @SafeVarargs + protected MultiMapIdSpec(Map<String, ?> firstId, Map<String, ?>... otherIds) { + this.ids = foldArguments(Function.identity(), firstId, otherIds); + } + + protected MultiMapIdSpec(ObjectId firstId, ObjectId... otherIds) { + this.ids = foldArguments(ObjectId::getIdSnapshot, firstId, otherIds); + } + + @Override + public Expression getQualifier(ObjEntity entity) { + List<Expression> expressions = new ArrayList<>(); + for(Map<String, ?> id : ids) { + expressions.add(matchAllDbExp(id, Expression.EQUAL_TO)); + } + + return or(expressions); + } } } diff --git a/cayenne-server/src/test/java/org/apache/cayenne/query/SelectById_RunIT.java b/cayenne-server/src/test/java/org/apache/cayenne/query/SelectById_RunIT.java index 9dfc5db..74dd0f4 100644 --- a/cayenne-server/src/test/java/org/apache/cayenne/query/SelectById_RunIT.java +++ b/cayenne-server/src/test/java/org/apache/cayenne/query/SelectById_RunIT.java @@ -18,13 +18,11 @@ ****************************************************************/ package org.apache.cayenne.query; -import static java.util.Collections.singletonMap; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertSame; - import java.sql.Types; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Map; import org.apache.cayenne.DataRow; import org.apache.cayenne.ObjectContext; @@ -36,13 +34,16 @@ 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.di.DataChannelInterceptor; -import org.apache.cayenne.unit.di.UnitTestClosure; import org.apache.cayenne.unit.di.server.CayenneProjects; import org.apache.cayenne.unit.di.server.ServerCase; import org.apache.cayenne.unit.di.server.UseServerRuntime; import org.junit.Before; import org.junit.Test; +import static java.util.Collections.singletonMap; +import static org.hamcrest.CoreMatchers.instanceOf; +import static org.junit.Assert.*; + @UseServerRuntime(CayenneProjects.TESTMAP_PROJECT) public class SelectById_RunIT extends ServerCase { @@ -85,7 +86,27 @@ public class SelectById_RunIT extends ServerCase { assertNotNull(a2); assertEquals("artist2", a2.getArtistName()); } - + + @Test + public void testIntPkMulti() 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)); + } + + @Test + public void testIntPkCollection() 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)); + } + @Test public void testIntPk_SelectFirst() throws Exception { createTwoArtists(); @@ -113,6 +134,19 @@ public class SelectById_RunIT extends ServerCase { } @Test + public void testMapPkMulti() 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)); + } + + @Test public void testObjectIdPk() throws Exception { createTwoArtists(); @@ -128,6 +162,19 @@ public class SelectById_RunIT extends ServerCase { } @Test + public void testObjectIdPkMulti() 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)); + } + + @Test public void testDataRowIntPk() throws Exception { createTwoArtists(); @@ -141,6 +188,73 @@ public class SelectById_RunIT extends ServerCase { } @Test + public void testDataRowMapPk() 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")); + } + + @Test + public void testDataRowObjectIdPk() 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")); + } + + @Test + public void testDataRowIntPkMulti() 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)); + } + + @Test + public void testDataRowMapPkMulti() 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)); + } + + @Test + public void testDataRowObjectIdPkMulti() 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)); + } + + + @Test public void testMetadataCacheKey() throws Exception { SelectById<Painting> q1 = SelectById.query(Painting.class, 4).localCache(); QueryMetadata md1 = q1.getMetaData(resolver); @@ -170,13 +284,13 @@ public class SelectById_RunIT extends ServerCase { assertNotEquals(md1.getCacheKey(), md4.getCacheKey()); SelectById<Painting> q5 = SelectById - .query(Painting.class, ObjectId.of("Painting", Painting.PAINTING_ID_PK_COLUMN, 4)).localCache(); + .query(Painting.class, ObjectId.of("Painting", Painting.PAINTING_ID_PK_COLUMN, 4)) + .localCache(); QueryMetadata md5 = q5.getMetaData(resolver); assertNotNull(md5); assertNotNull(md5.getCacheKey()); - // this query is just a different form of q1, so should hit the same - // cache entry + // this query is just a different form of q1, so should hit the same cache entry assertEquals(md1.getCacheKey(), md5.getCacheKey()); } @@ -186,34 +300,21 @@ public class SelectById_RunIT extends ServerCase { final Artist[] a3 = new Artist[1]; - assertEquals(1, interceptor.runWithQueryCounter(new UnitTestClosure() { - - @Override - public void execute() { - a3[0] = SelectById.query(Artist.class, 3).localCache("g1").selectOne(context); - assertNotNull(a3[0]); - assertEquals("artist3", a3[0].getArtistName()); - } + assertEquals(1, interceptor.runWithQueryCounter(() -> { + a3[0] = SelectById.query(Artist.class, 3).localCache("g1").selectOne(context); + assertNotNull(a3[0]); + assertEquals("artist3", a3[0].getArtistName()); })); - interceptor.runWithQueriesBlocked(new UnitTestClosure() { - - @Override - public void execute() { - Artist a3cached = SelectById.query(Artist.class, 3).localCache("g1").selectOne(context); - assertSame(a3[0], a3cached); - } + interceptor.runWithQueriesBlocked(() -> { + Artist a3cached = SelectById.query(Artist.class, 3).localCache("g1").selectOne(context); + assertSame(a3[0], a3cached); }); context.performGenericQuery(new RefreshQuery("g1")); - assertEquals(1, interceptor.runWithQueryCounter(new UnitTestClosure() { - - @Override - public void execute() { - SelectById.query(Artist.class, 3).localCache("g1").selectOne(context); - } - })); + assertEquals(1, interceptor.runWithQueryCounter(() -> + SelectById.query(Artist.class, 3).localCache("g1").selectOne(context))); } @Test @@ -222,19 +323,17 @@ public class SelectById_RunIT extends ServerCase { tPainting.insert(45, 3, "One"); tPainting.insert(48, 3, "Two"); - final Artist a3 = SelectById.query(Artist.class, 3).prefetch(Artist.PAINTING_ARRAY.joint()).selectOne(context); - - interceptor.runWithQueriesBlocked(new UnitTestClosure() { + final Artist a3 = SelectById.query(Artist.class, 3) + .prefetch(Artist.PAINTING_ARRAY.joint()) + .selectOne(context); - @Override - public void execute() { - assertNotNull(a3); - assertEquals("artist3", a3.getArtistName()); - assertEquals(2, a3.getPaintingArray().size()); + interceptor.runWithQueriesBlocked(() -> { + assertNotNull(a3); + assertEquals("artist3", a3.getArtistName()); + assertEquals(2, a3.getPaintingArray().size()); - a3.getPaintingArray().get(0).getPaintingTitle(); - a3.getPaintingArray().get(1).getPaintingTitle(); - } + a3.getPaintingArray().get(0).getPaintingTitle(); + a3.getPaintingArray().get(1).getPaintingTitle(); }); } }