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 34aaa780edd30f1d30c0c7a5f21f41cb3864f54f Author: Andrus Adamchik <[email protected]> AuthorDate: Sun Aug 30 13:44:28 2026 -0400 Query cleanup... Unwinding CacheableQuery also some reformatting --- .../org/apache/cayenne/query/CacheableQuery.java | 5 - .../org/apache/cayenne/query/FluentSelect.java | 83 +- .../org/apache/cayenne/query/MappedSelect.java | 16 +- .../java/org/apache/cayenne/query/SelectById.java | 1473 ++++++++++---------- .../cayenne/access/DataContextQueryCachingIT.java | 6 +- 5 files changed, 821 insertions(+), 762 deletions(-) diff --git a/cayenne/src/main/java/org/apache/cayenne/query/CacheableQuery.java b/cayenne/src/main/java/org/apache/cayenne/query/CacheableQuery.java index 970f98a8c..b2fd54b1a 100644 --- a/cayenne/src/main/java/org/apache/cayenne/query/CacheableQuery.java +++ b/cayenne/src/main/java/org/apache/cayenne/query/CacheableQuery.java @@ -19,9 +19,6 @@ package org.apache.cayenne.query; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - /** * Shared functionality for cacheable queries. * @@ -29,8 +26,6 @@ import org.slf4j.LoggerFactory; */ public abstract class CacheableQuery implements Query { - protected static final Logger LOGGER = LoggerFactory.getLogger(CacheableQuery.class); - abstract protected BaseQueryMetadata getBaseMetaData(); /** diff --git a/cayenne/src/main/java/org/apache/cayenne/query/FluentSelect.java b/cayenne/src/main/java/org/apache/cayenne/query/FluentSelect.java index 73d2517d7..1b1c2ef9d 100644 --- a/cayenne/src/main/java/org/apache/cayenne/query/FluentSelect.java +++ b/cayenne/src/main/java/org/apache/cayenne/query/FluentSelect.java @@ -41,7 +41,7 @@ import org.apache.cayenne.map.ObjEntity; * * @since 4.0 */ -public abstract class FluentSelect<T, S extends FluentSelect<T, S>> extends CacheableQuery implements Select<T> { +public abstract class FluentSelect<T, S extends FluentSelect<T, S>> implements Select<T> { // root protected Class<?> entityType; @@ -63,6 +63,8 @@ public abstract class FluentSelect<T, S extends FluentSelect<T, S>> extends Cach protected abstract ObjectSelectMetadata createMetadata(); + protected abstract ObjectSelectMetadata getBaseMetaData(); + protected Object resolveRoot(EntityResolver resolver) { Object root; if (entityType != null) { @@ -346,8 +348,8 @@ public abstract class FluentSelect<T, S extends FluentSelect<T, S>> extends Cach } public S cacheStrategy(QueryCacheStrategy strategy) { - setCacheStrategy(strategy); - setCacheGroup(null); + getBaseMetaData().setCacheStrategy(strategy); + getBaseMetaData().setCacheGroup(null); return castSelf(); } @@ -356,7 +358,7 @@ public abstract class FluentSelect<T, S extends FluentSelect<T, S>> extends Cach } public S cacheGroup(String cacheGroup) { - setCacheGroup(cacheGroup); + getBaseMetaData().setCacheGroup(cacheGroup); return castSelf(); } @@ -408,6 +410,79 @@ public abstract class FluentSelect<T, S extends FluentSelect<T, S>> extends Cach return cacheStrategy(QueryCacheStrategy.SHARED_CACHE); } + /** + * @since 3.0 + */ + public QueryCacheStrategy getCacheStrategy() { + return getBaseMetaData().getCacheStrategy(); + } + + /** + * @since 4.0 + */ + public String getCacheGroup() { + return getBaseMetaData().getCacheGroup(); + } + + /** + * Note that unlike {@link #cacheStrategy(QueryCacheStrategy)} this method preserves the + * existing cache group. To reset it, use {@link #cacheStrategy(QueryCacheStrategy, String)}. + * + * @since 3.0 + * @deprecated use {@link #cacheStrategy(QueryCacheStrategy, String)} + */ + @Deprecated(since = "5.0", forRemoval = true) + public void setCacheStrategy(QueryCacheStrategy strategy) { + getBaseMetaData().setCacheStrategy(strategy); + } + + /** + * @since 4.0 + * @deprecated use {@link #cacheGroup(String)} + */ + @Deprecated(since = "5.0", forRemoval = true) + public void setCacheGroup(String cacheGroup) { + getBaseMetaData().setCacheGroup(cacheGroup); + } + + /** + * @since 4.0 + * @deprecated use {@link #localCache()} + */ + @Deprecated(since = "5.0", forRemoval = true) + public void useLocalCache() { + getBaseMetaData().setCacheStrategy(QueryCacheStrategy.LOCAL_CACHE); + } + + /** + * @since 4.0 + * @deprecated use {@link #localCache(String)} + */ + @Deprecated(since = "5.0", forRemoval = true) + public void useLocalCache(String cacheGroup) { + getBaseMetaData().setCacheStrategy(QueryCacheStrategy.LOCAL_CACHE); + getBaseMetaData().setCacheGroup(cacheGroup); + } + + /** + * @since 4.0 + * @deprecated use {@link #sharedCache()} + */ + @Deprecated(since = "5.0", forRemoval = true) + public void useSharedCache() { + getBaseMetaData().setCacheStrategy(QueryCacheStrategy.SHARED_CACHE); + } + + /** + * @since 4.0 + * @deprecated use {@link #sharedCache(String)} + */ + @Deprecated(since = "5.0", forRemoval = true) + public void useSharedCache(String cacheGroup) { + getBaseMetaData().setCacheStrategy(QueryCacheStrategy.SHARED_CACHE); + getBaseMetaData().setCacheGroup(cacheGroup); + } + public int getStatementFetchSize() { return getBaseMetaData().getStatementFetchSize(); } diff --git a/cayenne/src/main/java/org/apache/cayenne/query/MappedSelect.java b/cayenne/src/main/java/org/apache/cayenne/query/MappedSelect.java index f87518113..e6062bc25 100644 --- a/cayenne/src/main/java/org/apache/cayenne/query/MappedSelect.java +++ b/cayenne/src/main/java/org/apache/cayenne/query/MappedSelect.java @@ -18,15 +18,14 @@ ****************************************************************/ package org.apache.cayenne.query; -import java.sql.Statement; -import java.util.List; -import java.util.Map; - import org.apache.cayenne.CayenneRuntimeException; import org.apache.cayenne.ObjectContext; import org.apache.cayenne.map.EntityResolver; import org.apache.cayenne.map.QueryDescriptor; +import java.sql.Statement; +import java.util.Map; + /** * A query that represents a named parameterized selecting query stored in the mapping. The * actual query is resolved during execution. @@ -147,17 +146,12 @@ public class MappedSelect<T> extends AbstractMappedQuery implements Select<T> { public MappedSelect<T> param(String name, Object value) { return (MappedSelect<T>) super.param(name, value); } - - - + @Override public T selectFirst(ObjectContext context) { return context.selectFirst(limit(1)); } - - - @Override protected Query createReplacementQuery(EntityResolver resolver) { QueryDescriptor descriptor = resolver.getQueryDescriptor(queryName); @@ -191,7 +185,7 @@ public class MappedSelect<T> extends AbstractMappedQuery implements Select<T> { selectQuery.pageSize(pageSize); } if (cacheStrategyOverride != null) { - selectQuery.setCacheStrategy(cacheStrategyOverride); + selectQuery.cacheStrategy(cacheStrategyOverride, selectQuery.getCacheGroup()); } } case QueryDescriptor.SQL_TEMPLATE -> { 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 d5e11659e..532942134 100644 --- a/cayenne/src/main/java/org/apache/cayenne/query/SelectById.java +++ b/cayenne/src/main/java/org/apache/cayenne/query/SelectById.java @@ -38,748 +38,743 @@ import static org.apache.cayenne.exp.ExpressionFactory.*; /** * A query to select objects by id. - * + * * @since 4.0 */ public class SelectById<T> extends IndirectQuery implements Select<T> { - private static final long serialVersionUID = -6589464349051607583L; - - final QueryRoot root; - final IdSpec idSpec; - final boolean fetchingDataRows; - - QueryCacheStrategy cacheStrategy; - String cacheGroup; - PrefetchTreeNode prefetches; - - /* 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); - } - - /** - * @since 5.0 - */ - public static <T> SelectById<T> queryMap(Class<T> entityType, Map<String, ?> id) { - QueryRoot root = new ByEntityTypeResolver(entityType); - IdSpec idSpec = new SingleMapIdSpec(checkIdMap(id)); - return new SelectById<>(root, idSpec); - } - - /** - * @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) { - if(ids == null) { - throw new CayenneRuntimeException("Null 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) { - if(ids == null) { - throw new CayenneRuntimeException("Null 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) { - if(ids == null) { - throw new CayenneRuntimeException("Null ids"); - } - - for(Map<String, ?> id : ids) { - checkIdMap(id); - } - - 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) { - if(ids == null) { - throw new CayenneRuntimeException("Null ids"); - } - - ids.forEach(SelectById::checkIdMap); - 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) { - throw new CayenneRuntimeException("Null 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) { - throw new CayenneRuntimeException("Null 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 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 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 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 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); - return new SelectById<>(root, idSpec); - } - - /** - * @since 4.2 - * @deprecated 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); - return new SelectById<>(root, idSpec); - } - - /** - * @since 4.2 - * @deprecated 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 = MultiMapIdSpec.ofMap(firstId, otherIds); - return new SelectById<>(root, idSpec); - } - - /** - * @since 4.2 - * @deprecated 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) { - checkObjectId(id, firstId.getEntityName()); - } - - QueryRoot root = new ByEntityNameResolver(firstId.getEntityName()); - IdSpec idSpec = MultiMapIdSpec.ofObjectId(firstId, otherIds); - return new SelectById<>(root, idSpec); - } - - - /* 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); - } - - /** - * @since 5.0 - */ - public static SelectById<DataRow> dataRowQueryMap(Class<?> entityType, Map<String, ?> id) { - QueryRoot root = new ByEntityTypeResolver(entityType); - IdSpec idSpec = new SingleMapIdSpec(checkIdMap(id)); - return new SelectById<>(root, idSpec, true); - } - - /** - * @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) { - if(ids == null) { - throw new CayenneRuntimeException("Null 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) { - if(ids == null) { - throw new CayenneRuntimeException("Null 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) { - if(ids == null) { - throw new CayenneRuntimeException("Null ids"); - } - - for(Map<String, ?> id : ids) { - checkIdMap(id); - } - - 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) { - if(ids == null) { - throw new CayenneRuntimeException("Null ids"); - } - - ids.forEach(SelectById::checkIdMap); - - 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) { - throw new CayenneRuntimeException("Null 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) { - throw new CayenneRuntimeException("Null 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 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 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 use {@link #dataRowQueryObjectId(ObjectId)} - */ - @Deprecated(since = "5.0", forRemoval = true) - public static SelectById<DataRow> dataRowQuery(ObjectId id) { - return dataRowQueryObjectId(id); - } - - /** - * @since 4.2 - * @deprecated 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); - return new SelectById<>(root, idSpec, true); - } - - /** - * @since 4.2 - * @deprecated 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 = MultiMapIdSpec.ofMap(firstId, otherIds); - return new SelectById<>(root, idSpec, true); - } - - /** - * @since 4.2 - * @deprecated 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) { - checkObjectId(id, firstId.getEntityName()); - } - - QueryRoot root = new ByEntityNameResolver(firstId.getEntityName()); - IdSpec idSpec = MultiMapIdSpec.ofObjectId(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 - public T selectFirst(ObjectContext context) { - return context.selectFirst(this); - } - - - - - /** - * Instructs Cayenne to look for query results in the "local" cache when - * running the query. This is a short-hand notation for: - * - * <pre> - * query.cacheStrategy(QueryCacheStrategy.LOCAL_CACHE, cacheGroup); - * </pre> - */ - public SelectById<T> localCache(String cacheGroup) { - return cacheStrategy(QueryCacheStrategy.LOCAL_CACHE, cacheGroup); - } - - /** - * Instructs Cayenne to look for query results in the "local" cache when - * running the query. This is a short-hand notation for: - * - * <pre> - * query.cacheStrategy(QueryCacheStrategy.LOCAL_CACHE); - * </pre> - */ - public SelectById<T> localCache() { - return cacheStrategy(QueryCacheStrategy.LOCAL_CACHE); - } - - /** - * Instructs Cayenne to look for query results in the "shared" cache when - * running the query. This is a short-hand notation for: - * - * <pre> - * query.cacheStrategy(QueryCacheStrategy.SHARED_CACHE, cacheGroup); - * </pre> - */ - public SelectById<T> sharedCache(String cacheGroup) { - return cacheStrategy(QueryCacheStrategy.SHARED_CACHE, cacheGroup); - } - - /** - * Instructs Cayenne to look for query results in the "shared" cache when - * running the query. This is a short-hand notation for: - * - * <pre> - * query.cacheStrategy(QueryCacheStrategy.SHARED_CACHE); - * </pre> - */ - public SelectById<T> sharedCache() { - return cacheStrategy(QueryCacheStrategy.SHARED_CACHE); - } - - public QueryCacheStrategy getCacheStrategy() { - return cacheStrategy; - } - - public SelectById<T> cacheStrategy(QueryCacheStrategy strategy) { - if (this.cacheStrategy != strategy) { - this.cacheStrategy = strategy; - this.replacementQuery = null; - } - - return this; - } - - public SelectById<T> cacheStrategy(QueryCacheStrategy strategy, String cacheGroup) { - return cacheStrategy(strategy).cacheGroup(cacheGroup); - } - - public String getCacheGroup() { - return cacheGroup; - } - - public SelectById<T> cacheGroup(String cacheGroup) { - this.cacheGroup = cacheGroup; - this.replacementQuery = null; - return this; - } - - public boolean isFetchingDataRows() { - return fetchingDataRows; - } - - /** - * Merges prefetch into the query prefetch tree. - * - * @return this object - */ - public SelectById<T> prefetch(PrefetchTreeNode prefetch) { - - if (prefetch == null) { - return this; - } - - if (prefetches == null) { - prefetches = new PrefetchTreeNode(); - } - - prefetches.merge(prefetch); - return this; - } - - /** - * Merges a prefetch path with specified semantics into the query prefetch - * tree. - * - * @return this object - */ - public SelectById<T> prefetch(String path, int semantics) { - - if (path == null) { - return this; - } - - if (prefetches == null) { - prefetches = new PrefetchTreeNode(); - } - - prefetches.addPath(path).setSemantics(semantics); - return this; - } - - public PrefetchTreeNode getPrefetches() { - return prefetches; - } - - @Override - protected Query createReplacementQuery(EntityResolver resolver) { - ObjEntity entity = root.resolve(resolver); - - ObjectSelect<?> query = new ObjectSelect<>() - .entityName(entity.getName()) - .where(idSpec.getQualifier(entity)) - .cacheStrategy(cacheStrategy, cacheGroup); - if(prefetches != null) { - query.prefetch(prefetches); - } - if(fetchingDataRows) { - query.fetchDataRows(); - } - return query; - } - - 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()); - } - - 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); - } - } - - 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"); - } - } - - private static Map<String, ?> checkIdMap(Map<String, ?> id) { - if(id == null || id.isEmpty()) { - throw new CayenneRuntimeException("Null or empty id map"); - } - - return id; - } - - @SafeVarargs - private static <E, R> Collection<R> foldArguments(Function<E, R> mapper, E first, E... other) { - List<R> result = new ArrayList<>(1 + other.length); - result.add(mapper.apply(first)); - for(E next : other) { - result.add(mapper.apply(next)); - } - 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); - } - - 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; - } - - @Override - public Expression getQualifier(ObjEntity entity) { - return matchDbExp(resolveSinglePkName(entity), id); - } - } - - protected static class MultiScalarIdSpec implements IdSpec { - - private final Collection<Object> ids; - - protected MultiScalarIdSpec(Object firstId, Object... otherIds) { - this.ids = foldArguments(Function.identity(), firstId, otherIds); - } - - 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) { - Expression expression = matchAllDbExp(id, Expression.EQUAL_TO); - return expression == null ? expFalse() : expression; - } - } - - protected static class MultiMapIdSpec implements IdSpec { - - private final Collection<Map<String, ?>> ids; - - @SafeVarargs + private static final long serialVersionUID = -6589464349051607583L; + + final QueryRoot root; + final IdSpec idSpec; + final boolean fetchingDataRows; + + QueryCacheStrategy cacheStrategy; + String cacheGroup; + PrefetchTreeNode prefetches; + + /* 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); + } + + /** + * @since 5.0 + */ + public static <T> SelectById<T> queryMap(Class<T> entityType, Map<String, ?> id) { + QueryRoot root = new ByEntityTypeResolver(entityType); + IdSpec idSpec = new SingleMapIdSpec(checkIdMap(id)); + return new SelectById<>(root, idSpec); + } + + /** + * @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) { + if (ids == null) { + throw new CayenneRuntimeException("Null 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) { + if (ids == null) { + throw new CayenneRuntimeException("Null 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) { + if (ids == null) { + throw new CayenneRuntimeException("Null ids"); + } + + for (Map<String, ?> id : ids) { + checkIdMap(id); + } + + 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) { + if (ids == null) { + throw new CayenneRuntimeException("Null ids"); + } + + ids.forEach(SelectById::checkIdMap); + 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) { + throw new CayenneRuntimeException("Null 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) { + throw new CayenneRuntimeException("Null 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 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 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 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 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); + return new SelectById<>(root, idSpec); + } + + /** + * @since 4.2 + * @deprecated 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); + return new SelectById<>(root, idSpec); + } + + /** + * @since 4.2 + * @deprecated 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 = MultiMapIdSpec.ofMap(firstId, otherIds); + return new SelectById<>(root, idSpec); + } + + /** + * @since 4.2 + * @deprecated 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) { + checkObjectId(id, firstId.getEntityName()); + } + + QueryRoot root = new ByEntityNameResolver(firstId.getEntityName()); + IdSpec idSpec = MultiMapIdSpec.ofObjectId(firstId, otherIds); + return new SelectById<>(root, idSpec); + } + + + /* 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); + } + + /** + * @since 5.0 + */ + public static SelectById<DataRow> dataRowQueryMap(Class<?> entityType, Map<String, ?> id) { + QueryRoot root = new ByEntityTypeResolver(entityType); + IdSpec idSpec = new SingleMapIdSpec(checkIdMap(id)); + return new SelectById<>(root, idSpec, true); + } + + /** + * @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) { + if (ids == null) { + throw new CayenneRuntimeException("Null 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) { + if (ids == null) { + throw new CayenneRuntimeException("Null 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) { + if (ids == null) { + throw new CayenneRuntimeException("Null ids"); + } + + for (Map<String, ?> id : ids) { + checkIdMap(id); + } + + 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) { + if (ids == null) { + throw new CayenneRuntimeException("Null ids"); + } + + ids.forEach(SelectById::checkIdMap); + + 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) { + throw new CayenneRuntimeException("Null 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) { + throw new CayenneRuntimeException("Null 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 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 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 use {@link #dataRowQueryObjectId(ObjectId)} + */ + @Deprecated(since = "5.0", forRemoval = true) + public static SelectById<DataRow> dataRowQuery(ObjectId id) { + return dataRowQueryObjectId(id); + } + + /** + * @since 4.2 + * @deprecated 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); + return new SelectById<>(root, idSpec, true); + } + + /** + * @since 4.2 + * @deprecated 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 = MultiMapIdSpec.ofMap(firstId, otherIds); + return new SelectById<>(root, idSpec, true); + } + + /** + * @since 4.2 + * @deprecated 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) { + checkObjectId(id, firstId.getEntityName()); + } + + QueryRoot root = new ByEntityNameResolver(firstId.getEntityName()); + IdSpec idSpec = MultiMapIdSpec.ofObjectId(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 + public T selectFirst(ObjectContext context) { + return context.selectFirst(this); + } + + /** + * Instructs Cayenne to look for query results in the "local" cache when + * running the query. This is a short-hand notation for: + * + * <pre> + * query.cacheStrategy(QueryCacheStrategy.LOCAL_CACHE, cacheGroup); + * </pre> + */ + public SelectById<T> localCache(String cacheGroup) { + return cacheStrategy(QueryCacheStrategy.LOCAL_CACHE, cacheGroup); + } + + /** + * Instructs Cayenne to look for query results in the "local" cache when + * running the query. This is a short-hand notation for: + * + * <pre> + * query.cacheStrategy(QueryCacheStrategy.LOCAL_CACHE); + * </pre> + */ + public SelectById<T> localCache() { + return cacheStrategy(QueryCacheStrategy.LOCAL_CACHE); + } + + /** + * Instructs Cayenne to look for query results in the "shared" cache when + * running the query. This is a short-hand notation for: + * + * <pre> + * query.cacheStrategy(QueryCacheStrategy.SHARED_CACHE, cacheGroup); + * </pre> + */ + public SelectById<T> sharedCache(String cacheGroup) { + return cacheStrategy(QueryCacheStrategy.SHARED_CACHE, cacheGroup); + } + + /** + * Instructs Cayenne to look for query results in the "shared" cache when + * running the query. This is a short-hand notation for: + * + * <pre> + * query.cacheStrategy(QueryCacheStrategy.SHARED_CACHE); + * </pre> + */ + public SelectById<T> sharedCache() { + return cacheStrategy(QueryCacheStrategy.SHARED_CACHE); + } + + public QueryCacheStrategy getCacheStrategy() { + return cacheStrategy; + } + + public SelectById<T> cacheStrategy(QueryCacheStrategy strategy) { + if (this.cacheStrategy != strategy) { + this.cacheStrategy = strategy; + this.replacementQuery = null; + } + + return this; + } + + public SelectById<T> cacheStrategy(QueryCacheStrategy strategy, String cacheGroup) { + return cacheStrategy(strategy).cacheGroup(cacheGroup); + } + + public String getCacheGroup() { + return cacheGroup; + } + + public SelectById<T> cacheGroup(String cacheGroup) { + this.cacheGroup = cacheGroup; + this.replacementQuery = null; + return this; + } + + public boolean isFetchingDataRows() { + return fetchingDataRows; + } + + /** + * Merges prefetch into the query prefetch tree. + * + * @return this object + */ + public SelectById<T> prefetch(PrefetchTreeNode prefetch) { + + if (prefetch == null) { + return this; + } + + if (prefetches == null) { + prefetches = new PrefetchTreeNode(); + } + + prefetches.merge(prefetch); + return this; + } + + /** + * Merges a prefetch path with specified semantics into the query prefetch + * tree. + * + * @return this object + */ + public SelectById<T> prefetch(String path, int semantics) { + + if (path == null) { + return this; + } + + if (prefetches == null) { + prefetches = new PrefetchTreeNode(); + } + + prefetches.addPath(path).setSemantics(semantics); + return this; + } + + public PrefetchTreeNode getPrefetches() { + return prefetches; + } + + @Override + protected Query createReplacementQuery(EntityResolver resolver) { + ObjEntity entity = root.resolve(resolver); + + ObjectSelect<?> query = new ObjectSelect<>() + .entityName(entity.getName()) + .where(idSpec.getQualifier(entity)) + .cacheStrategy(cacheStrategy, cacheGroup); + if (prefetches != null) { + query.prefetch(prefetches); + } + if (fetchingDataRows) { + query.fetchDataRows(); + } + return query; + } + + 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()); + } + + 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); + } + } + + 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"); + } + } + + private static Map<String, ?> checkIdMap(Map<String, ?> id) { + if (id == null || id.isEmpty()) { + throw new CayenneRuntimeException("Null or empty id map"); + } + + return id; + } + + @SafeVarargs + private static <E, R> Collection<R> foldArguments(Function<E, R> mapper, E first, E... other) { + List<R> result = new ArrayList<>(1 + other.length); + result.add(mapper.apply(first)); + for (E next : other) { + result.add(mapper.apply(next)); + } + 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); + } + + 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; + } + + @Override + public Expression getQualifier(ObjEntity entity) { + return matchDbExp(resolveSinglePkName(entity), id); + } + } + + protected static class MultiScalarIdSpec implements IdSpec { + + private final Collection<Object> ids; + + protected MultiScalarIdSpec(Object firstId, Object... otherIds) { + this.ids = foldArguments(Function.identity(), firstId, otherIds); + } + + 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) { + Expression expression = matchAllDbExp(id, Expression.EQUAL_TO); + return expression == null ? expFalse() : expression; + } + } + + protected static class MultiMapIdSpec implements IdSpec { + + private final Collection<Map<String, ?>> ids; + + @SafeVarargs 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)); - } - - 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 - public Expression getQualifier(ObjEntity entity) { - List<Expression> expressions = new ArrayList<>(); - for(Map<String, ?> id : ids) { - Expression expression = matchAllDbExp(id, Expression.EQUAL_TO); - if(expression != null) { - expressions.add(expression); - } - } - - return expressions.isEmpty() ? expFalse() : or(expressions); - } - } - - private static class ByEntityTypeResolver implements QueryRoot { - private final Class<?> entityType; - - public ByEntityTypeResolver(Class<?> entityType) { - this.entityType = entityType; - } - - @Override - public ObjEntity resolve(EntityResolver resolver) { - return resolver.getObjEntity(entityType); - } - } - - private static class ByEntityNameResolver implements QueryRoot { - private final String entityName; - - public ByEntityNameResolver(String entityName) { - this.entityName = entityName; - } - - @Override - public ObjEntity resolve(EntityResolver resolver) { - return resolver.getObjEntity(entityName); - } - } + 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)); + } + + 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 + public Expression getQualifier(ObjEntity entity) { + List<Expression> expressions = new ArrayList<>(); + for (Map<String, ?> id : ids) { + Expression expression = matchAllDbExp(id, Expression.EQUAL_TO); + if (expression != null) { + expressions.add(expression); + } + } + + return expressions.isEmpty() ? expFalse() : or(expressions); + } + } + + private static class ByEntityTypeResolver implements QueryRoot { + private final Class<?> entityType; + + public ByEntityTypeResolver(Class<?> entityType) { + this.entityType = entityType; + } + + @Override + public ObjEntity resolve(EntityResolver resolver) { + return resolver.getObjEntity(entityType); + } + } + + private static class ByEntityNameResolver implements QueryRoot { + private final String entityName; + + public ByEntityNameResolver(String entityName) { + this.entityName = entityName; + } + + @Override + public ObjEntity resolve(EntityResolver resolver) { + return resolver.getObjEntity(entityName); + } + } } diff --git a/cayenne/src/test/java/org/apache/cayenne/access/DataContextQueryCachingIT.java b/cayenne/src/test/java/org/apache/cayenne/access/DataContextQueryCachingIT.java index 608f06efc..57514bf0a 100644 --- a/cayenne/src/test/java/org/apache/cayenne/access/DataContextQueryCachingIT.java +++ b/cayenne/src/test/java/org/apache/cayenne/access/DataContextQueryCachingIT.java @@ -103,7 +103,7 @@ public class DataContextQueryCachingIT { List<?> rows2 = mockupDataRows(4); engine.reset(); engine.addExpectedResult(select, rows2); - select.setCacheStrategy(QueryCacheStrategy.LOCAL_CACHE_REFRESH); + select.cacheStrategy(QueryCacheStrategy.LOCAL_CACHE_REFRESH); List<?> freshResultRows = context.performQuery(select); assertEquals(1, engine.getRunCount()); assertEquals(rows2, freshResultRows); @@ -141,7 +141,7 @@ public class DataContextQueryCachingIT { List<?> rows2 = mockupDataRows(5); engine.reset(); engine.addExpectedResult(select, rows2); - select.setCacheStrategy(QueryCacheStrategy.SHARED_CACHE_REFRESH); + select.cacheStrategy(QueryCacheStrategy.SHARED_CACHE_REFRESH); List<?> freshResultRows = context.performQuery(select); assertEquals(1, engine.getRunCount()); assertEquals(rows2, freshResultRows); @@ -178,7 +178,7 @@ public class DataContextQueryCachingIT { List<?> rows2 = mockupDataRows(4); engine.reset(); engine.addExpectedResult(select, rows2); - select.setCacheStrategy(QueryCacheStrategy.LOCAL_CACHE_REFRESH); + select.cacheStrategy(QueryCacheStrategy.LOCAL_CACHE_REFRESH); List<?> freshResultRows = context.performQuery(select); assertEquals(1, engine.getRunCount());
