From c00e3f6b29c615de5ada2e959912ec9fad2eb600 Mon Sep 17 00:00:00 2001 From: John Blum Date: Tue, 23 Jan 2018 17:07:46 -0800 Subject: [PATCH] DATACASS-512 - Polish. Resolves #PR-118. --- .../core/AsyncCassandraOperations.java | 33 +++++---- .../core/AsyncCassandraTemplate.java | 61 ++++++++++------ .../cassandra/core/CassandraOperations.java | 33 +++++---- .../cassandra/core/CassandraTemplate.java | 70 +++++++++++-------- .../core/ReactiveCassandraOperations.java | 31 ++++---- .../core/ReactiveCassandraTemplate.java | 37 ++++++---- .../data/cassandra/core/StatementFactory.java | 52 +++++++------- .../data/cassandra/repository/CountQuery.java | 3 +- .../cassandra/repository/ExistsQuery.java | 3 +- .../data/cassandra/repository/Query.java | 5 +- .../query/AbstractCassandraQuery.java | 35 +++++++--- .../query/AbstractReactiveCassandraQuery.java | 45 ++++++++---- .../query/CassandraQueryExecution.java | 5 +- .../CassandraRepositoryQuerySupport.java | 9 +-- .../query/PartTreeCassandraQuery.java | 4 +- .../repository/query/ProjectionUtil.java | 32 +++++---- .../query/QueryStatementCreator.java | 53 +++++++------- .../ReactiveCassandraQueryExecution.java | 10 +-- .../query/ReactivePartTreeCassandraQuery.java | 4 +- .../ReactiveStringBasedCassandraQuery.java | 8 +-- .../query/StringBasedCassandraQuery.java | 8 +-- ...syncCassandraTemplateIntegrationTests.java | 5 +- .../CassandraTemplateIntegrationTests.java | 7 +- .../core/CassandraTemplateUnitTests.java | 8 ++- ...tiveCassandraTemplateIntegrationTests.java | 5 +- .../ReactiveCassandraTemplateUnitTests.java | 11 +-- .../core/StatementFactoryUnitTests.java | 3 +- .../QueryDerivationIntegrationTests.java | 8 ++- ...veCassandraRepositoryIntegrationTests.java | 9 +-- ...RepositoryReturnTypesIntegrationTests.java | 4 +- .../PartTreeCassandraQueryUnitTests.java | 5 +- ...activePartTreeCassandraQueryUnitTests.java | 14 ++-- ...iveStringBasedCassandraQueryUnitTests.java | 5 +- 33 files changed, 368 insertions(+), 257 deletions(-) diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/AsyncCassandraOperations.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/AsyncCassandraOperations.java index 2d59f3def..37b2d86a1 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/AsyncCassandraOperations.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/AsyncCassandraOperations.java @@ -223,19 +223,22 @@ public interface AsyncCassandraOperations { /** * Returns the number of rows for the given entity class. * - * @param entityClass must not be {@literal null}. + * @param entityClass {@link Class type} of the entity; must not be {@literal null}. * @return the number of existing entities. - * @throws DataAccessException if there is any problem executing the query. + * @throws DataAccessException if any problem occurs while executing the query. */ ListenableFuture count(Class entityClass) throws DataAccessException; /** * Returns the number of rows for the given entity class applying {@link Query}. * - * @param query must not be {@literal null}. - * @param entityClass must not be {@literal null}. + * This overridden method allows users to further refine the selection criteria using a {@link Query} predicate + * to determine how many entities of the given {@link Class type} match the criteria. + * + * @param query user-provided count {@link Query} to execute; must not be {@literal null}. + * @param entityClass {@link Class type} of the entity; must not be {@literal null}. * @return the number of existing entities. - * @throws DataAccessException if there is any problem executing the query. + * @throws DataAccessException if any problem occurs while executing the query. * @since 2.1 */ ListenableFuture count(Query query, Class entityClass) throws DataAccessException; @@ -243,22 +246,22 @@ public interface AsyncCassandraOperations { /** * Determine whether a row of {@code entityClass} with the given {@code id} exists. * - * @param id the Id value. For single primary keys it's the plain value. For composite primary keys either the - * {@link org.springframework.data.cassandra.core.mapping.PrimaryKeyClass} or - * {@link org.springframework.data.cassandra.core.mapping.MapId}. Must not be {@literal null}. - * @param entityClass must not be {@literal null}. - * @return {@literal true}, if the object exists. - * @throws DataAccessException if there is any problem executing the query. + * @param id Id value. For single primary keys it's the plain value. For composite primary keys either, it's + * an instance of either {@link org.springframework.data.cassandra.core.mapping.PrimaryKeyClass} + * or {@link org.springframework.data.cassandra.core.mapping.MapId}. Must not be {@literal null}. + * @param entityClass {@link Class type} of the entity; must not be {@literal null}. + * @return {@literal true} if the object exists. + * @throws DataAccessException if any problem occurs while executing the query. */ ListenableFuture exists(Object id, Class entityClass) throws DataAccessException; /** * Determine whether the result for {@code entityClass} {@link Query} yields at least one row. * - * @param query must not be {@literal null}. - * @param entityClass The entity type must not be {@literal null}. - * @return true, if the object exists. - * @throws DataAccessException if there is any problem executing the query. + * @param query user-provided exists {@link Query} to execute; must not be {@literal null}. + * @param entityClass {@link Class type} of the entity; must not be {@literal null}. + * @return {@literal true} if the object exists. + * @throws DataAccessException if any problem occurs while executing the query. * @since 2.1 */ ListenableFuture exists(Query query, Class entityClass) throws DataAccessException; diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/AsyncCassandraTemplate.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/AsyncCassandraTemplate.java index a6e0f9133..679cf8c1c 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/AsyncCassandraTemplate.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/AsyncCassandraTemplate.java @@ -178,16 +178,24 @@ public class AsyncCassandraTemplate implements AsyncCassandraOperations { } /** - * Returns the {@link CassandraMappingContext} used by this template to access mapping meta-data used to store (map) - * objects to Cassandra tables. + * Returns the {@link CassandraMappingContext} used by this template to access mapping meta-data + * in order to store (map) objects to Cassandra tables. * * @return the {@link CassandraMappingContext} used by this template. - * @see CassandraMappingContext + * @see org.springframework.data.cassandra.core.mapping.CassandraMappingContext */ protected MappingContext, CassandraPersistentProperty> getMappingContext() { return this.mappingContext; } + private CassandraPersistentEntity getRequiredPersistentEntity(Object entity) { + return getRequiredPersistentEntity(entity.getClass()); + } + + private CassandraPersistentEntity getRequiredPersistentEntity(Class entityType) { + return getMappingContext().getRequiredPersistentEntity(ClassUtils.getUserClass(entityType)); + } + /** * Returns the {@link StatementFactory} used by this template to construct and run Cassandra CQL statements. * @@ -199,7 +207,11 @@ public class AsyncCassandraTemplate implements AsyncCassandraOperations { } private CqlIdentifier getTableName(Object entity) { - return getMappingContext().getRequiredPersistentEntity(ClassUtils.getUserClass(entity)).getTableName(); + return getRequiredPersistentEntity(entity).getTableName(); + } + + private CqlIdentifier getTableName(Class entityType) { + return getRequiredPersistentEntity(entityType).getTableName(); } // ------------------------------------------------------------------------- @@ -400,8 +412,7 @@ public class AsyncCassandraTemplate implements AsyncCassandraOperations { Assert.notNull(entityClass, "Entity type must not be null"); - Select select = QueryBuilder.select().countAll() - .from(getMappingContext().getRequiredPersistentEntity(entityClass).getTableName().toCql()); + Select select = QueryBuilder.select().countAll().from(getTableName(entityClass).toCql()); return getAsyncCqlOperations().queryForObject(select, Long.class); } @@ -415,8 +426,7 @@ public class AsyncCassandraTemplate implements AsyncCassandraOperations { Assert.notNull(query, "Query must not be null"); Assert.notNull(entityClass, "Entity type must not be null"); - RegularStatement count = statementFactory.count(query, - getMappingContext().getRequiredPersistentEntity(entityClass)); + RegularStatement count = getStatementFactory().count(query, getRequiredPersistentEntity(entityClass)); ListenableFuture result = getAsyncCqlOperations().queryForObject(count, Long.class); @@ -432,7 +442,7 @@ public class AsyncCassandraTemplate implements AsyncCassandraOperations { Assert.notNull(id, "Id must not be null"); Assert.notNull(entityClass, "Entity type must not be null"); - CassandraPersistentEntity entity = getMappingContext().getRequiredPersistentEntity(entityClass); + CassandraPersistentEntity entity = getRequiredPersistentEntity(entityClass); Select select = QueryBuilder.select().from(entity.getTableName().toCql()); @@ -451,8 +461,8 @@ public class AsyncCassandraTemplate implements AsyncCassandraOperations { Assert.notNull(query, "Query must not be null"); Assert.notNull(entityClass, "Entity type must not be null"); - RegularStatement select = statementFactory.select(query.limit(1), - getMappingContext().getRequiredPersistentEntity(entityClass)); + RegularStatement select = getStatementFactory() + .select(query.limit(1), getRequiredPersistentEntity(entityClass)); return new MappingListenableFutureAdapter<>(getAsyncCqlOperations().queryForResultSet(select), resultSet -> resultSet.iterator().hasNext()); @@ -467,7 +477,7 @@ public class AsyncCassandraTemplate implements AsyncCassandraOperations { Assert.notNull(id, "Id must not be null"); Assert.notNull(entityClass, "Entity type must not be null"); - CassandraPersistentEntity entity = getMappingContext().getRequiredPersistentEntity(entityClass); + CassandraPersistentEntity entity = getRequiredPersistentEntity(entityClass); Select select = QueryBuilder.select().all().from(entity.getTableName().toCql()); @@ -495,8 +505,8 @@ public class AsyncCassandraTemplate implements AsyncCassandraOperations { Insert insert = QueryUtils.createInsertQuery(getTableName(entity).toCql(), entity, options, getConverter()); - return new MappingListenableFutureAdapter<>(getAsyncCqlOperations().execute(new AsyncStatementCallback(insert)), - WriteResult::of); + return new MappingListenableFutureAdapter<>( + getAsyncCqlOperations().execute(new AsyncStatementCallback(insert)), WriteResult::of); } /* (non-Javadoc) @@ -518,8 +528,8 @@ public class AsyncCassandraTemplate implements AsyncCassandraOperations { Update update = QueryUtils.createUpdateQuery(getTableName(entity).toCql(), entity, options, getConverter()); - return new MappingListenableFutureAdapter<>(getAsyncCqlOperations().execute(new AsyncStatementCallback(update)), - WriteResult::of); + return new MappingListenableFutureAdapter<>( + getAsyncCqlOperations().execute(new AsyncStatementCallback(update)), WriteResult::of); } /* (non-Javadoc) @@ -541,8 +551,8 @@ public class AsyncCassandraTemplate implements AsyncCassandraOperations { Delete delete = QueryUtils.createDeleteQuery(getTableName(entity).toCql(), entity, options, getConverter()); - return new MappingListenableFutureAdapter<>(getAsyncCqlOperations().execute(new AsyncStatementCallback(delete)), - WriteResult::of); + return new MappingListenableFutureAdapter<>(getAsyncCqlOperations() + .execute(new AsyncStatementCallback(delete)), WriteResult::of); } /* (non-Javadoc) @@ -554,7 +564,7 @@ public class AsyncCassandraTemplate implements AsyncCassandraOperations { Assert.notNull(id, "Id must not be null"); Assert.notNull(entityClass, "Entity type must not be null"); - CassandraPersistentEntity entity = getMappingContext().getRequiredPersistentEntity(entityClass); + CassandraPersistentEntity entity = getRequiredPersistentEntity(entityClass); Delete delete = QueryBuilder.delete().from(entity.getTableName().toCql()); @@ -571,8 +581,7 @@ public class AsyncCassandraTemplate implements AsyncCassandraOperations { Assert.notNull(entityClass, "Entity type must not be null"); - Truncate truncate = QueryBuilder - .truncate(getMappingContext().getRequiredPersistentEntity(entityClass).getTableName().toCql()); + Truncate truncate = QueryBuilder.truncate(getTableName(entityClass).toCql()); return new MappingListenableFutureAdapter<>(getAsyncCqlOperations().execute(truncate), aBoolean -> null); } @@ -581,6 +590,10 @@ public class AsyncCassandraTemplate implements AsyncCassandraOperations { // Implementation hooks and helper methods // ------------------------------------------------------------------------- + private int getConfiguredFetchSize(Session session) { + return session.getCluster().getConfiguration().getQueryOptions().getFetchSize(); + } + @SuppressWarnings("ConstantConditions") private int getEffectiveFetchSize(Statement statement) { @@ -589,14 +602,16 @@ public class AsyncCassandraTemplate implements AsyncCassandraOperations { } if (getAsyncCqlOperations() instanceof CassandraAccessor) { + CassandraAccessor accessor = (CassandraAccessor) getAsyncCqlOperations(); + if (accessor.getFetchSize() != -1) { return accessor.getFetchSize(); } } - return getAsyncCqlOperations().execute((AsyncSessionCallback) session -> AsyncResult - .forValue(session.getCluster().getConfiguration().getQueryOptions().getFetchSize())).completable().join(); + return getAsyncCqlOperations().execute((AsyncSessionCallback) session -> + AsyncResult.forValue(getConfiguredFetchSize(session))).completable().join(); } static class MappingListenableFutureAdapter diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/CassandraOperations.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/CassandraOperations.java index 560da6178..39d87eb18 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/CassandraOperations.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/CassandraOperations.java @@ -250,19 +250,22 @@ public interface CassandraOperations { /** * Returns the number of rows for the given entity class. * - * @param entityClass must not be {@literal null}. + * @param entityClass {@link Class type} of the entity; must not be {@literal null}. * @return the number of existing entities. - * @throws DataAccessException if there is any problem executing the query. + * @throws DataAccessException if any problem occurs while executing the query. */ long count(Class entityClass) throws DataAccessException; /** * Returns the number of rows for the given entity class applying {@link Query}. * - * @param query must not be {@literal null}. - * @param entityClass must not be {@literal null}. + * This overridden method allows users to further refine the selection criteria using a {@link Query} predicate + * to determine how many entities of the given {@link Class type} match the criteria. + * + * @param query user-defined count {@link Query} to execute; must not be {@literal null}. + * @param entityClass {@link Class type} of the entity; must not be {@literal null}. * @return the number of existing entities. - * @throws DataAccessException if there is any problem executing the query. + * @throws DataAccessException if any problem occurs while executing the query. * @since 2.1 */ long count(Query query, Class entityClass) throws DataAccessException; @@ -270,22 +273,22 @@ public interface CassandraOperations { /** * Determine whether a row of {@code entityClass} with the given {@code id} exists. * - * @param id the Id value. For single primary keys it's the plain value. For composite primary keys either the - * {@link org.springframework.data.cassandra.core.mapping.PrimaryKeyClass} or - * {@link org.springframework.data.cassandra.core.mapping.MapId}. Must not be {@literal null}. - * @param entityClass The entity type must not be {@literal null}. - * @return true, if the object exists. - * @throws DataAccessException if there is any problem executing the query. + * @param id Id value. For single primary keys it's the plain value. For composite primary keys either, it's + * an instance of either {@link org.springframework.data.cassandra.core.mapping.PrimaryKeyClass} + * or {@link org.springframework.data.cassandra.core.mapping.MapId}. Must not be {@literal null}. + * @param entityClass {@link Class type} of the entity; must not be {@literal null}. + * @return {@literal true} if the object exists. + * @throws DataAccessException if any problem occurs while executing the query. */ boolean exists(Object id, Class entityClass) throws DataAccessException; /** * Determine whether the result for {@code entityClass} {@link Query} yields at least one row. * - * @param query must not be {@literal null}. - * @param entityClass The entity type must not be {@literal null}. - * @return true, if the object exists. - * @throws DataAccessException if there is any problem executing the query. + * @param query user-defined exists {@link Query} to execute; must not be {@literal null}. + * @param entityClass {@link Class type} of the entity; must not be {@literal null}. + * @return {@literal true} if the object exists. + * @throws DataAccessException if any problem occurs while executing the query. * @since 2.1 */ boolean exists(Query query, Class entityClass) throws DataAccessException; diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/CassandraTemplate.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/CassandraTemplate.java index 4e84a2a01..39b185639 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/CassandraTemplate.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/CassandraTemplate.java @@ -15,13 +15,13 @@ */ package org.springframework.data.cassandra.core; -import lombok.NonNull; -import lombok.Value; - import java.util.List; import java.util.stream.Stream; import java.util.stream.StreamSupport; +import lombok.NonNull; +import lombok.Value; + import org.springframework.dao.DataAccessException; import org.springframework.data.cassandra.SessionFactory; import org.springframework.data.cassandra.core.convert.CassandraConverter; @@ -172,16 +172,24 @@ public class CassandraTemplate implements CassandraOperations { } /** - * Returns the {@link CassandraMappingContext} used by this template to access mapping meta-data used to store (map) - * object to Cassandra tables. + * Returns the {@link CassandraMappingContext} used by this template to access mapping meta-data + * in order to store (map) object to Cassandra tables. * * @return the {@link CassandraMappingContext} used by this template. - * @see CassandraMappingContext + * @see org.springframework.data.cassandra.core.mapping.CassandraMappingContext */ protected MappingContext, CassandraPersistentProperty> getMappingContext() { return this.mappingContext; } + private CassandraPersistentEntity getRequiredPersistentEntity(Object entity) { + return getRequiredPersistentEntity(entity.getClass()); + } + + private CassandraPersistentEntity getRequiredPersistentEntity(Class entityType) { + return getMappingContext().getRequiredPersistentEntity(ClassUtils.getUserClass(entityType)); + } + /** * Returns the {@link StatementFactory} used by this template to construct and run Cassandra CQL statements. * @@ -192,6 +200,18 @@ public class CassandraTemplate implements CassandraOperations { return this.statementFactory; } + private CqlIdentifier getTableName(Object entity) { + return getRequiredPersistentEntity(entity).getTableName(); + } + + /* (non-Javadoc) + * @see org.springframework.data.cassandra.core.CassandraOperations#getTableName(java.lang.Class) + */ + @Override + public CqlIdentifier getTableName(Class entityClass) { + return getRequiredPersistentEntity(entityClass).getTableName(); + } + // ------------------------------------------------------------------------- // Methods dealing with static CQL // ------------------------------------------------------------------------- @@ -379,8 +399,7 @@ public class CassandraTemplate implements CassandraOperations { Assert.notNull(entityClass, "Entity type must not be null"); - Select select = QueryBuilder.select().countAll() - .from(getMappingContext().getRequiredPersistentEntity(entityClass).getTableName().toCql()); + Select select = QueryBuilder.select().countAll().from(getTableName(entityClass).toCql()); Long count = getCqlOperations().queryForObject(select, Long.class); @@ -396,8 +415,7 @@ public class CassandraTemplate implements CassandraOperations { Assert.notNull(query, "Query must not be null"); Assert.notNull(entityClass, "Entity type must not be null"); - RegularStatement count = statementFactory.count(query, - getMappingContext().getRequiredPersistentEntity(entityClass)); + RegularStatement count = getStatementFactory().count(query, getRequiredPersistentEntity(entityClass)); Long result = getCqlOperations().queryForObject(count, Long.class); @@ -413,7 +431,7 @@ public class CassandraTemplate implements CassandraOperations { Assert.notNull(id, "Id must not be null"); Assert.notNull(entityClass, "Entity type must not be null"); - CassandraPersistentEntity entity = getMappingContext().getRequiredPersistentEntity(entityClass); + CassandraPersistentEntity entity = getRequiredPersistentEntity(entityClass); Select select = QueryBuilder.select().from(entity.getTableName().toCql()); @@ -431,8 +449,8 @@ public class CassandraTemplate implements CassandraOperations { Assert.notNull(query, "Query must not be null"); Assert.notNull(entityClass, "Entity type must not be null"); - RegularStatement select = statementFactory.select(query.limit(1), - getMappingContext().getRequiredPersistentEntity(entityClass)); + RegularStatement select = getStatementFactory() + .select(query.limit(1), getRequiredPersistentEntity(entityClass)); return getCqlOperations().queryForResultSet(select).iterator().hasNext(); } @@ -446,7 +464,7 @@ public class CassandraTemplate implements CassandraOperations { Assert.notNull(id, "Id must not be null"); Assert.notNull(entityClass, "Entity type must not be null"); - CassandraPersistentEntity entity = getMappingContext().getRequiredPersistentEntity(entityClass); + CassandraPersistentEntity entity = getRequiredPersistentEntity(entityClass); Select select = QueryBuilder.select().all().from(entity.getTableName().toCql()); @@ -472,7 +490,7 @@ public class CassandraTemplate implements CassandraOperations { Assert.notNull(entity, "Entity must not be null"); Assert.notNull(options, "InsertOptions must not be null"); - Insert insert = QueryUtils.createInsertQuery(getTableName(entity.getClass()).toCql(), entity, options, converter); + Insert insert = QueryUtils.createInsertQuery(getTableName(entity).toCql(), entity, options, getConverter()); // noinspection ConstantConditions return getCqlOperations().execute(new StatementCallback(insert)); @@ -495,7 +513,7 @@ public class CassandraTemplate implements CassandraOperations { Assert.notNull(entity, "Entity must not be null"); Assert.notNull(options, "UpdateOptions must not be null"); - Update update = QueryUtils.createUpdateQuery(getTableName(entity.getClass()).toCql(), entity, options, converter); + Update update = QueryUtils.createUpdateQuery(getTableName(entity).toCql(), entity, options, getConverter()); // noinspection ConstantConditions return getCqlOperations().execute(new StatementCallback(update)); @@ -518,7 +536,7 @@ public class CassandraTemplate implements CassandraOperations { Assert.notNull(entity, "Entity must not be null"); Assert.notNull(options, "QueryOptions must not be null"); - Delete delete = QueryUtils.createDeleteQuery(getTableName(entity.getClass()).toCql(), entity, options, converter); + Delete delete = QueryUtils.createDeleteQuery(getTableName(entity).toCql(), entity, options, getConverter()); // noinspection ConstantConditions return getCqlOperations().execute(new StatementCallback(delete)); @@ -533,7 +551,7 @@ public class CassandraTemplate implements CassandraOperations { Assert.notNull(id, "Id must not be null"); Assert.notNull(entityClass, "Entity type must not be null"); - CassandraPersistentEntity entity = getMappingContext().getRequiredPersistentEntity(entityClass); + CassandraPersistentEntity entity = getRequiredPersistentEntity(entityClass); Delete delete = QueryBuilder.delete().from(entity.getTableName().toCql()); @@ -550,8 +568,7 @@ public class CassandraTemplate implements CassandraOperations { Assert.notNull(entityClass, "Entity type must not be null"); - Truncate truncate = QueryBuilder - .truncate(getMappingContext().getRequiredPersistentEntity(entityClass).getTableName().toCql()); + Truncate truncate = QueryBuilder.truncate(getTableName(entityClass).toCql()); getCqlOperations().execute(truncate); } @@ -560,12 +577,8 @@ public class CassandraTemplate implements CassandraOperations { // Implementation hooks and helper methods // ------------------------------------------------------------------------- - /* (non-Javadoc) - * @see org.springframework.data.cassandra.core.CassandraOperations#getTableName(java.lang.Class) - */ - @Override - public CqlIdentifier getTableName(Class entityClass) { - return getMappingContext().getRequiredPersistentEntity(ClassUtils.getUserClass(entityClass)).getTableName(); + private int getConfiguredFetchSize(Session session) { + return session.getCluster().getConfiguration().getQueryOptions().getFetchSize(); } @SuppressWarnings("ConstantConditions") @@ -576,14 +589,15 @@ public class CassandraTemplate implements CassandraOperations { } if (getCqlOperations() instanceof CassandraAccessor) { + CassandraAccessor accessor = (CassandraAccessor) getCqlOperations(); + if (accessor.getFetchSize() != -1) { return accessor.getFetchSize(); } } - return getCqlOperations().execute( - (SessionCallback) session -> session.getCluster().getConfiguration().getQueryOptions().getFetchSize()); + return getCqlOperations().execute(this::getConfiguredFetchSize); } /* (non-Javadoc) diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/ReactiveCassandraOperations.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/ReactiveCassandraOperations.java index df4e7f030..53dfaae2c 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/ReactiveCassandraOperations.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/ReactiveCassandraOperations.java @@ -158,19 +158,22 @@ public interface ReactiveCassandraOperations { /** * Returns the number of rows for the given entity class. * - * @param entityClass must not be {@literal null}. + * @param entityClass {@link Class type} of the entity; must not be {@literal null}. * @return the number of existing entities. - * @throws DataAccessException if there is any problem issuing the execution. + * @throws DataAccessException if any problem occurs while executing the query. */ Mono count(Class entityClass) throws DataAccessException; /** * Returns the number of rows for the given entity class applying {@link Query}. * - * @param query must not be {@literal null}. - * @param entityClass must not be {@literal null}. + * This overridden method allows users to further refine the selection criteria using a {@link Query} predicate + * to determine how many entities of the given {@link Class type} match the criteria. + * + * @param query user-defined count {@link Query} to execute; must not be {@literal null}. + * @param entityClass {@link Class type} of the entity; must not be {@literal null}. * @return the number of existing entities. - * @throws DataAccessException if there is any problem executing the query. + * @throws DataAccessException if any problem occurs while executing the query. * @since 2.1 */ Mono count(Query query, Class entityClass) throws DataAccessException; @@ -178,22 +181,22 @@ public interface ReactiveCassandraOperations { /** * Determine whether a row of {@code entityClass} with the given {@code id} exists. * - * @param id the Id value. For single primary keys it's the plain value. For composite primary keys either the - * {@link org.springframework.data.cassandra.core.mapping.PrimaryKeyClass} or - * {@link org.springframework.data.cassandra.core.mapping.MapId}. Must not be {@literal null}. - * @param entityClass must not be {@literal null}. + * @param id Id value. For single primary keys it's the plain value. For composite primary keys either, it's + * an instance of either {@link org.springframework.data.cassandra.core.mapping.PrimaryKeyClass} + * or {@link org.springframework.data.cassandra.core.mapping.MapId}. Must not be {@literal null}. + * @param entityClass {@link Class type} of the entity; must not be {@literal null}. * @return {@literal true} if the object exists. - * @throws DataAccessException if there is any problem issuing the execution. + * @throws DataAccessException if any problem occurs while executing the query. */ Mono exists(Object id, Class entityClass) throws DataAccessException; /** * Determine whether the result for {@code entityClass} {@link Query} yields at least one row. * - * @param query must not be {@literal null}. - * @param entityClass The entity type must not be {@literal null}. - * @return true, if the object exists. - * @throws DataAccessException if there is any problem executing the query. + * @param query user-defined exists {@link Query} to execute; must not be {@literal null}. + * @param entityClass {@link Class type} of the entity; must not be {@literal null}. + * @return {@literal true} if the object exists. + * @throws DataAccessException if any problem occurs while executing the query. * @since 2.1 */ Mono exists(Query query, Class entityClass) throws DataAccessException; diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/ReactiveCassandraTemplate.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/ReactiveCassandraTemplate.java index 1bfcac50c..4c34bdcbc 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/ReactiveCassandraTemplate.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/ReactiveCassandraTemplate.java @@ -17,6 +17,7 @@ package org.springframework.data.cassandra.core; import lombok.NonNull; import lombok.Value; + import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; @@ -189,6 +190,14 @@ public class ReactiveCassandraTemplate implements ReactiveCassandraOperations { return this.cqlOperations; } + private CassandraPersistentEntity getRequiredPersistentEntity(Object entity) { + return getRequiredPersistentEntity(entity.getClass()); + } + + private CassandraPersistentEntity getRequiredPersistentEntity(Class entityType) { + return getMappingContext().getRequiredPersistentEntity(ClassUtils.getUserClass(entityType)); + } + /** * Returns the {@link StatementFactory} used by this template to construct and run Cassandra CQL statements. * @@ -199,9 +208,12 @@ public class ReactiveCassandraTemplate implements ReactiveCassandraOperations { return this.statementFactory; } - /* (non-Javadoc) */ private CqlIdentifier getTableName(Object entity) { - return getMappingContext().getRequiredPersistentEntity(ClassUtils.getUserClass(entity)).getTableName(); + return getRequiredPersistentEntity(entity).getTableName(); + } + + private CqlIdentifier getTableName(Class entityType) { + return getRequiredPersistentEntity(entityType).getTableName(); } // ------------------------------------------------------------------------- @@ -322,8 +334,7 @@ public class ReactiveCassandraTemplate implements ReactiveCassandraOperations { Assert.notNull(entityClass, "Entity type must not be null"); - Select select = QueryBuilder.select().countAll() - .from(getMappingContext().getRequiredPersistentEntity(entityClass).getTableName().toCql()); + Select select = QueryBuilder.select().countAll().from(getTableName(entityClass).toCql()); return getReactiveCqlOperations().queryForObject(select, Long.class); } @@ -337,8 +348,7 @@ public class ReactiveCassandraTemplate implements ReactiveCassandraOperations { Assert.notNull(query, "Query must not be null"); Assert.notNull(entityClass, "Entity type must not be null"); - RegularStatement count = statementFactory.count(query, - getMappingContext().getRequiredPersistentEntity(entityClass)); + RegularStatement count = getStatementFactory().count(query, getRequiredPersistentEntity(entityClass)); return getReactiveCqlOperations().queryForObject(count, Long.class); } @@ -352,7 +362,7 @@ public class ReactiveCassandraTemplate implements ReactiveCassandraOperations { Assert.notNull(id, "Id must not be null"); Assert.notNull(entityClass, "Entity type must not be null"); - CassandraPersistentEntity entity = getMappingContext().getRequiredPersistentEntity(entityClass); + CassandraPersistentEntity entity = getRequiredPersistentEntity(entityClass); Select select = QueryBuilder.select().from(entity.getTableName().toCql()); @@ -370,8 +380,8 @@ public class ReactiveCassandraTemplate implements ReactiveCassandraOperations { Assert.notNull(query, "Query must not be null"); Assert.notNull(entityClass, "Entity type must not be null"); - RegularStatement select = statementFactory.select(query.limit(1), - getMappingContext().getRequiredPersistentEntity(entityClass)); + RegularStatement select = getStatementFactory() + .select(query.limit(1), getRequiredPersistentEntity(entityClass)); return getReactiveCqlOperations().queryForRows(select).hasElements(); } @@ -385,7 +395,7 @@ public class ReactiveCassandraTemplate implements ReactiveCassandraOperations { Assert.notNull(id, "Id must not be null"); Assert.notNull(entityClass, "Entity type must not be null"); - CassandraPersistentEntity entity = getMappingContext().getRequiredPersistentEntity(entityClass); + CassandraPersistentEntity entity = getRequiredPersistentEntity(entityClass); Select select = QueryBuilder.select().all().from(entity.getTableName().toCql()); @@ -433,7 +443,7 @@ public class ReactiveCassandraTemplate implements ReactiveCassandraOperations { Assert.notNull(entity, "Entity must not be null"); Assert.notNull(options, "UpdateOptions must not be null"); - Update update = QueryUtils.createUpdateQuery(getTableName(entity).toCql(), entity, options, converter); + Update update = QueryUtils.createUpdateQuery(getTableName(entity).toCql(), entity, options, getConverter()); return getReactiveCqlOperations().execute(new StatementCallback(update)).next(); } @@ -469,7 +479,7 @@ public class ReactiveCassandraTemplate implements ReactiveCassandraOperations { Assert.notNull(id, "Id must not be null"); Assert.notNull(entityClass, "Entity type must not be null"); - CassandraPersistentEntity entity = getMappingContext().getRequiredPersistentEntity(entityClass); + CassandraPersistentEntity entity = getRequiredPersistentEntity(entityClass); Delete delete = QueryBuilder.delete().from(entity.getTableName().toCql()); @@ -486,8 +496,7 @@ public class ReactiveCassandraTemplate implements ReactiveCassandraOperations { Assert.notNull(entityClass, "Entity type must not be null"); - Truncate truncate = QueryBuilder - .truncate(getMappingContext().getRequiredPersistentEntity(entityClass).getTableName().toCql()); + Truncate truncate = QueryBuilder.truncate(getTableName(entityClass).toCql()); return getReactiveCqlOperations().execute(truncate).then(); } diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/StatementFactory.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/StatementFactory.java index 0e643c2b3..84b62c700 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/StatementFactory.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/StatementFactory.java @@ -125,6 +125,26 @@ public class StatementFactory { return this.updateMapper; } + /** + * Create a {@literal COUNT} statement by mapping {@link Query} to {@link Select}. + * + * @param query user-defined count {@link Query} to execute; must not be {@literal null}. + * @param entity {@link CassandraPersistentEntity entity} to count; must not be {@literal null}. + * @return the rendered {@link RegularStatement}. + * @since 2.1 + */ + public RegularStatement count(Query query, CassandraPersistentEntity entity) { + + Assert.notNull(query, "Query must not be null"); + Assert.notNull(entity, "Entity must not be null"); + + Filter filter = getQueryMapper().getMappedObject(query, entity); + + List selectors = Collections.singletonList(FunctionCall.from("COUNT", 1L)); + + return createSelect(query, entity, filter, selectors); + } + /** * Create a {@literal SELECT} statement by mapping {@link Query} to {@link Select}. * @@ -144,26 +164,6 @@ public class StatementFactory { return createSelect(query, entity, filter, selectors); } - /** - * Create a {@literal COUNT} statement by mapping {@link Query} to {@link Select}. - * - * @param query must not be {@literal null}. - * @param entity must not be {@literal null}. - * @return the rendered {@link RegularStatement}. - * @since 2.1 - */ - public RegularStatement count(Query query, CassandraPersistentEntity entity) { - - Assert.notNull(query, "Query must not be null"); - Assert.notNull(entity, "Entity must not be null"); - - Filter filter = getQueryMapper().getMappedObject(query, entity); - - List selectors = Collections.singletonList(FunctionCall.from("COUNT", 1L)); - - return createSelect(query, entity, filter, selectors); - } - private Select createSelect(Query query, CassandraPersistentEntity entity, Filter filter, List selectors) { @@ -194,10 +194,11 @@ public class StatementFactory { if (selectors.isEmpty()) { select = QueryBuilder.select().all().from(from.toCql()); } else { + Selection selection = QueryBuilder.select(); - selectors.forEach(selector -> { - selector.getAlias().map(CqlIdentifier::toCql).ifPresent(getSelection(selection, selector)::as); - }); + + selectors.forEach(selector -> + selector.getAlias().map(CqlIdentifier::toCql).ifPresent(getSelection(selection, selector)::as)); select = selection.from(from.toCql()); } @@ -206,6 +207,7 @@ public class StatementFactory { } if (sort.isSorted()) { + List orderings = new ArrayList<>(); for (Order order : sort) { @@ -459,7 +461,7 @@ public class StatementFactory { return QueryBuilder.containsKey(columnName, predicate.getValue()); } - throw new IllegalArgumentException( - String.format("Criteria %s %s %s not supported", columnName, predicate.getOperator(), predicate.getValue())); + throw new IllegalArgumentException(String.format("Criteria %s %s %s not supported", + columnName, predicate.getOperator(), predicate.getValue())); } } diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/CountQuery.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/CountQuery.java index 0fae5f55e..5d4755129 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/CountQuery.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/CountQuery.java @@ -30,8 +30,8 @@ import org.springframework.core.annotation.AliasFor; * @author Mark Paluch * @since 2.1 */ -@Retention(RetentionPolicy.RUNTIME) @Target({ ElementType.METHOD, ElementType.ANNOTATION_TYPE }) +@Retention(RetentionPolicy.RUNTIME) @Documented @Query(count = true) public @interface CountQuery { @@ -42,4 +42,5 @@ public @interface CountQuery { */ @AliasFor(annotation = Query.class) String value() default ""; + } diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/ExistsQuery.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/ExistsQuery.java index 41552ad66..6a7c7c745 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/ExistsQuery.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/ExistsQuery.java @@ -30,8 +30,8 @@ import org.springframework.core.annotation.AliasFor; * @author Mark Paluch * @since 2.1 */ -@Retention(RetentionPolicy.RUNTIME) @Target({ ElementType.METHOD, ElementType.ANNOTATION_TYPE }) +@Retention(RetentionPolicy.RUNTIME) @Documented @Query(exists = true) public @interface ExistsQuery { @@ -42,4 +42,5 @@ public @interface ExistsQuery { */ @AliasFor(annotation = Query.class) String value() default ""; + } diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/Query.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/Query.java index 74bab9abf..02b7af34d 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/Query.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/Query.java @@ -50,16 +50,17 @@ public @interface Query { boolean allowFiltering() default false; /** - * Returns whether the query defined should be executed as count projection. + * Returns whether the defined query should be executed as a count projection. * * @since 2.1 */ boolean count() default false; /** - * Returns whether the query defined should be executed as exists projection. + * Returns whether the defined query should be executed as an exists projection. * * @since 2.1 */ boolean exists() default false; + } diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/AbstractCassandraQuery.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/AbstractCassandraQuery.java index 249da5d5c..eddc02abc 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/AbstractCassandraQuery.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/AbstractCassandraQuery.java @@ -17,6 +17,8 @@ package org.springframework.data.cassandra.repository.query; import org.springframework.core.convert.converter.Converter; import org.springframework.data.cassandra.core.CassandraOperations; +import org.springframework.data.cassandra.core.convert.CassandraConverter; +import org.springframework.data.cassandra.core.mapping.CassandraMappingContext; import org.springframework.data.cassandra.repository.query.CassandraQueryExecution.CollectionExecution; import org.springframework.data.cassandra.repository.query.CassandraQueryExecution.ExistsExecution; import org.springframework.data.cassandra.repository.query.CassandraQueryExecution.ResultProcessingConverter; @@ -44,6 +46,17 @@ public abstract class AbstractCassandraQuery extends CassandraRepositoryQuerySup private final CassandraOperations operations; + private static CassandraConverter toConverter(CassandraOperations operations) { + + Assert.notNull(operations, "CassandraOperations must not be null"); + + return operations.getConverter(); + } + + private static CassandraMappingContext toMappingContext(CassandraOperations operations) { + return toConverter(operations).getMappingContext(); + } + /** * Create a new {@link AbstractCassandraQuery} from the given {@link CassandraQueryMethod} and * {@link CassandraOperations}. @@ -53,13 +66,17 @@ public abstract class AbstractCassandraQuery extends CassandraRepositoryQuerySup */ public AbstractCassandraQuery(CassandraQueryMethod queryMethod, CassandraOperations operations) { - super(queryMethod, operations.getConverter().getMappingContext()); - - Assert.notNull(operations, "CassandraOperations must not be null"); + super(queryMethod, toMappingContext(operations)); this.operations = operations; } + /** + * Return a reference to the {@link CassandraOperations} used to execute this Cassandra query. + * + * @return a reference to the {@link CassandraOperations} used to execute this Cassandra query. + * @see org.springframework.data.cassandra.core.CassandraOperations + */ protected CassandraOperations getOperations() { return this.operations; } @@ -71,7 +88,7 @@ public abstract class AbstractCassandraQuery extends CassandraRepositoryQuerySup @Override public Object execute(Object[] parameters) { - CassandraParameterAccessor parameterAccessor = new ConvertingParameterAccessor(getOperations().getConverter(), + CassandraParameterAccessor parameterAccessor = new ConvertingParameterAccessor(toConverter(getOperations()), new CassandraParametersParameterAccessor(getQueryMethod(), parameters)); ResultProcessor resultProcessor = getQueryMethod().getResultProcessor().withDynamicProjection(parameterAccessor); @@ -79,7 +96,7 @@ public abstract class AbstractCassandraQuery extends CassandraRepositoryQuerySup Statement statement = createQuery(parameterAccessor); CassandraQueryExecution queryExecution = getExecution(parameterAccessor, new ResultProcessingConverter( - resultProcessor, getOperations().getConverter().getMappingContext(), getEntityInstantiators())); + resultProcessor, toMappingContext(getOperations()), getEntityInstantiators())); Class resultType = resolveResultType(resultProcessor); @@ -91,7 +108,7 @@ public abstract class AbstractCassandraQuery extends CassandraRepositoryQuerySup CassandraReturnedType returnedType = new CassandraReturnedType(resultProcessor.getReturnedType(), getOperations().getConverter().getCustomConversions()); - return (returnedType.isProjecting() ? returnedType.getDomainType() : returnedType.getReturnedType()); + return returnedType.isProjecting() ? returnedType.getDomainType() : returnedType.getReturnedType(); } /** @@ -110,6 +127,7 @@ public abstract class AbstractCassandraQuery extends CassandraRepositoryQuerySup */ private CassandraQueryExecution getExecution(CassandraParameterAccessor parameterAccessor, Converter resultProcessing) { + return new ResultProcessingExecution(getExecutionToWrap(parameterAccessor, resultProcessing), resultProcessing); } @@ -136,7 +154,7 @@ public abstract class AbstractCassandraQuery extends CassandraRepositoryQuerySup /** * Returns whether the query should get a count projection applied. * - * @return + * @return a boolean value indicating whether the query is a count projection. * @since 2.1 */ protected abstract boolean isCountQuery(); @@ -144,8 +162,9 @@ public abstract class AbstractCassandraQuery extends CassandraRepositoryQuerySup /** * Returns whether the query should get an exists projection applied. * - * @return + * @return a boolean value indicating whether the query is an exists projection. * @since 2.1 */ protected abstract boolean isExistsQuery(); + } diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/AbstractReactiveCassandraQuery.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/AbstractReactiveCassandraQuery.java index 4ffb92a10..4469cb860 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/AbstractReactiveCassandraQuery.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/AbstractReactiveCassandraQuery.java @@ -22,6 +22,8 @@ import org.reactivestreams.Publisher; import org.springframework.core.convert.converter.Converter; import org.springframework.data.cassandra.core.CassandraOperations; import org.springframework.data.cassandra.core.ReactiveCassandraOperations; +import org.springframework.data.cassandra.core.convert.CassandraConverter; +import org.springframework.data.cassandra.core.mapping.CassandraMappingContext; import org.springframework.data.cassandra.repository.query.ReactiveCassandraQueryExecution.CollectionExecution; import org.springframework.data.cassandra.repository.query.ReactiveCassandraQueryExecution.ExistsExecution; import org.springframework.data.cassandra.repository.query.ReactiveCassandraQueryExecution.ResultProcessingConverter; @@ -45,6 +47,17 @@ public abstract class AbstractReactiveCassandraQuery extends CassandraRepository private final ReactiveCassandraOperations operations; + private static CassandraConverter toConverter(ReactiveCassandraOperations operations) { + + Assert.notNull(operations, "ReactiveCassandraOperations must not be null"); + + return operations.getConverter(); + } + + private static CassandraMappingContext toMappingContext(ReactiveCassandraOperations operations) { + return toConverter(operations).getMappingContext(); + } + /** * Create a new {@link AbstractReactiveCassandraQuery} from the given {@link CassandraQueryMethod} and * {@link CassandraOperations}. @@ -54,9 +67,7 @@ public abstract class AbstractReactiveCassandraQuery extends CassandraRepository */ public AbstractReactiveCassandraQuery(ReactiveCassandraQueryMethod method, ReactiveCassandraOperations operations) { - super(method, operations.getConverter().getMappingContext()); - - Assert.notNull(operations, "ReactiveCassandraOperations must not be null"); + super(method, toMappingContext(operations)); this.operations = operations; } @@ -80,22 +91,27 @@ public abstract class AbstractReactiveCassandraQuery extends CassandraRepository */ @Override public Object execute(Object[] parameters) { - return (getQueryMethod().hasReactiveWrapperParameter() ? executeDeferred(parameters) : executeNow(parameters)); + + return getQueryMethod().hasReactiveWrapperParameter() + ? executeDeferred(parameters) + : executeNow(parameters); } @SuppressWarnings("unchecked") private Object executeDeferred(Object[] parameters) { - return (getQueryMethod().isCollectionQuery() ? Flux.defer(() -> (Publisher) execute(parameters)) - : Mono.defer(() -> (Mono) execute(parameters))); + + return getQueryMethod().isCollectionQuery() + ? Flux.defer(() -> (Publisher) execute(parameters)) + : Mono.defer(() -> (Mono) execute(parameters)); } private Object executeNow(Object[] parameters) { ReactiveCassandraParameterAccessor parameterAccessor = - new ReactiveCassandraParameterAccessor(getQueryMethod(), parameters); + new ReactiveCassandraParameterAccessor(getQueryMethod(), parameters); CassandraParameterAccessor convertingParameterAccessor = new ConvertingParameterAccessor( - getReactiveCassandraOperations().getConverter(), parameterAccessor); + toConverter(getReactiveCassandraOperations()), parameterAccessor); Statement statement = createQuery(convertingParameterAccessor); @@ -103,7 +119,7 @@ public abstract class AbstractReactiveCassandraQuery extends CassandraRepository .withDynamicProjection(convertingParameterAccessor); ReactiveCassandraQueryExecution queryExecution = getExecution(new ResultProcessingConverter(resultProcessor, - getReactiveCassandraOperations().getConverter().getMappingContext(), getEntityInstantiators())); + toMappingContext(getReactiveCassandraOperations()), getEntityInstantiators())); Class resultType = resolveResultType(resultProcessor); @@ -113,7 +129,7 @@ public abstract class AbstractReactiveCassandraQuery extends CassandraRepository private Class resolveResultType(ResultProcessor resultProcessor) { CassandraReturnedType returnedType = new CassandraReturnedType(resultProcessor.getReturnedType(), - getReactiveCassandraOperations().getConverter().getCustomConversions()); + toConverter(getReactiveCassandraOperations()).getCustomConversions()); return (returnedType.isProjecting() ? returnedType.getDomainType() : returnedType.getReturnedType()); } @@ -139,8 +155,8 @@ public abstract class AbstractReactiveCassandraQuery extends CassandraRepository if (getQueryMethod().isCollectionQuery()) { return new CollectionExecution(getReactiveCassandraOperations()); } else if (isCountQuery()) { - return ((statement, type) -> new SingleEntityExecution(getReactiveCassandraOperations()).execute(statement, - Long.class)); + return ((statement, type) -> + new SingleEntityExecution(getReactiveCassandraOperations()).execute(statement, Long.class)); } else if (isExistsQuery()) { return new ExistsExecution(getReactiveCassandraOperations()); } else { @@ -151,7 +167,7 @@ public abstract class AbstractReactiveCassandraQuery extends CassandraRepository /** * Returns whether the query should get a count projection applied. * - * @return + * @return a boolean value indicating whether the query is a count projection. * @since 2.1 */ protected abstract boolean isCountQuery(); @@ -159,8 +175,9 @@ public abstract class AbstractReactiveCassandraQuery extends CassandraRepository /** * Returns whether the query should get an exists projection applied. * - * @return + * @return a boolean value indicating whether the query is an exists projection. * @since 2.1 */ protected abstract boolean isExistsQuery(); + } diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/CassandraQueryExecution.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/CassandraQueryExecution.java index 513cb376f..699fff1f3 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/CassandraQueryExecution.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/CassandraQueryExecution.java @@ -153,7 +153,7 @@ interface CassandraQueryExecution { @Override public Object execute(Statement statement, Class type) { - ResultSet resultSet = operations.getCqlOperations().queryForResultSet(statement); + ResultSet resultSet = this.operations.getCqlOperations().queryForResultSet(statement); Iterator iterator = resultSet.iterator(); @@ -161,9 +161,10 @@ interface CassandraQueryExecution { Row row = iterator.next(); - if (!iterator.hasNext() && ProjectionUtil.isCountProjection(row)) { + if (!iterator.hasNext() && ProjectionUtil.qualifiesAsCountProjection(row)) { Object object = row.getObject(0); + return ((Number) object).longValue() > 0; } diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/CassandraRepositoryQuerySupport.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/CassandraRepositoryQuerySupport.java index 8d4d8f5ef..960893a88 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/CassandraRepositoryQuerySupport.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/CassandraRepositoryQuerySupport.java @@ -60,12 +60,7 @@ public abstract class CassandraRepositoryQuerySupport implements RepositoryQuery */ @Deprecated public CassandraRepositoryQuerySupport(CassandraQueryMethod queryMethod) { - - Assert.notNull(queryMethod, "CassandraQueryMethod must not be null"); - - this.queryMethod = queryMethod; - this.instantiators = new EntityInstantiators(); - this.queryStatementCreator = new QueryStatementCreator(queryMethod, new CassandraMappingContext()); + this(queryMethod, new CassandraMappingContext()); } /** @@ -100,7 +95,7 @@ public abstract class CassandraRepositoryQuerySupport implements RepositoryQuery } protected QueryStatementCreator getQueryStatementCreator() { - return queryStatementCreator; + return this.queryStatementCreator; } @RequiredArgsConstructor diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/PartTreeCassandraQuery.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/PartTreeCassandraQuery.java index dbe8f0406..c3d15007b 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/PartTreeCassandraQuery.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/PartTreeCassandraQuery.java @@ -112,7 +112,7 @@ public class PartTreeCassandraQuery extends AbstractCassandraQuery { */ @Override protected boolean isCountQuery() { - return tree.isCountProjection(); + return getTree().isCountProjection(); } /* (non-Javadoc) @@ -120,6 +120,6 @@ public class PartTreeCassandraQuery extends AbstractCassandraQuery { */ @Override protected boolean isExistsQuery() { - return tree.isExistsProjection(); + return getTree().isExistsProjection(); } } diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/ProjectionUtil.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/ProjectionUtil.java index 5700eddb5..9fe64b8a5 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/ProjectionUtil.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/ProjectionUtil.java @@ -15,12 +15,12 @@ */ package org.springframework.data.cassandra.repository.query; -import lombok.experimental.UtilityClass; - import java.util.Arrays; import java.util.HashSet; import java.util.Set; +import lombok.experimental.UtilityClass; + import com.datastax.driver.core.ColumnDefinitions; import com.datastax.driver.core.DataType; import com.datastax.driver.core.Row; @@ -37,19 +37,6 @@ class ProjectionUtil { private final static Set NUMERIC_TYPES = new HashSet<>(Arrays.asList(DataType.bigint(), DataType.varint(), DataType.smallint(), DataType.cint(), DataType.counter(), DataType.tinyint())); - /** - * Determine wether the {@link Row} qualifies for a count projection. Count projection candidates have a single - * numeric column. - * - * @param row - * @return - */ - static boolean isCountProjection(Row row) { - - ColumnDefinitions columnDefinitions = row.getColumnDefinitions(); - return columnDefinitions.size() == 1 && NUMERIC_TYPES.contains(columnDefinitions.getType(0)); - } - /** * Determine whether multiple {@code boolean} flags are set. Allowed is at most a single {@literal true} value. * @@ -59,4 +46,19 @@ class ProjectionUtil { static boolean hasAmbiguousProjectionFlags(Boolean... flags) { return Arrays.stream(flags).filter(Boolean::booleanValue).count() > 1; } + + /** + * Determine whether the {@link Row} qualifies as a count projection. + * + * Count projection candidates have a single numeric column. + * + * @param row {@link Row} to evaluate for a count projection. + * @return a boolean value indicating whether the {@link Row} qualifies as a count projection. + */ + static boolean qualifiesAsCountProjection(Row row) { + + ColumnDefinitions columnDefinitions = row.getColumnDefinitions(); + + return columnDefinitions.size() == 1 && NUMERIC_TYPES.contains(columnDefinitions.getType(0)); + } } diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/QueryStatementCreator.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/QueryStatementCreator.java index 1a03df846..6e978ecea 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/QueryStatementCreator.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/QueryStatementCreator.java @@ -15,13 +15,11 @@ */ package org.springframework.data.cassandra.repository.query; -import lombok.RequiredArgsConstructor; - import java.util.Optional; import java.util.function.Function; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import lombok.RequiredArgsConstructor; + import org.springframework.data.cassandra.core.StatementFactory; import org.springframework.data.cassandra.core.cql.QueryOptions; import org.springframework.data.cassandra.core.cql.QueryOptionsUtil; @@ -32,6 +30,9 @@ import org.springframework.data.mapping.context.MappingContext; import org.springframework.data.repository.query.QueryCreationException; import org.springframework.data.repository.query.parser.PartTree; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.datastax.driver.core.RegularStatement; import com.datastax.driver.core.SimpleStatement; import com.datastax.driver.core.Statement; @@ -52,6 +53,10 @@ class QueryStatementCreator { private final MappingContext, CassandraPersistentProperty> mappingContext; + private CassandraPersistentEntity requirePersistentEntity() { + return this.mappingContext.getRequiredPersistentEntity(this.queryMethod.getDomainClass()); + } + /** * Create a {@literal SELECT} {@link Statement} from a {@link PartTree} and apply query options. * @@ -65,10 +70,7 @@ class QueryStatementCreator { Function function = query -> { - CassandraPersistentEntity persistentEntity = mappingContext - .getRequiredPersistentEntity(queryMethod.getDomainClass()); - - RegularStatement statement = statementFactory.select(query, persistentEntity); + RegularStatement statement = statementFactory.select(query, requirePersistentEntity()); if (LOG.isDebugEnabled()) { LOG.debug(String.format("Created query [%s].", statement)); @@ -93,10 +95,7 @@ class QueryStatementCreator { Function function = query -> { - CassandraPersistentEntity persistentEntity = mappingContext - .getRequiredPersistentEntity(queryMethod.getDomainClass()); - - RegularStatement statement = statementFactory.count(query, persistentEntity); + RegularStatement statement = statementFactory.count(query, requirePersistentEntity()); if (LOG.isDebugEnabled()) { LOG.debug(String.format("Created query [%s].", statement)); @@ -122,10 +121,7 @@ class QueryStatementCreator { Function function = query -> { - CassandraPersistentEntity persistentEntity = mappingContext - .getRequiredPersistentEntity(queryMethod.getDomainClass()); - - RegularStatement statement = statementFactory.select(query.limit(1), persistentEntity); + RegularStatement statement = statementFactory.select(query.limit(1), requirePersistentEntity()); if (LOG.isDebugEnabled()) { LOG.debug(String.format("Created query [%s].", statement)); @@ -148,7 +144,8 @@ class QueryStatementCreator { T doWithQuery(CassandraParameterAccessor parameterAccessor, PartTree tree, Function function) { - CassandraQueryCreator queryCreator = new CassandraQueryCreator(tree, parameterAccessor, mappingContext); + CassandraQueryCreator queryCreator = + new CassandraQueryCreator(tree, parameterAccessor, this.mappingContext); Query query = queryCreator.createQuery(); @@ -158,9 +155,7 @@ class QueryStatementCreator { query = query.limit(tree.getMaxResults()); } - if (this.queryMethod.getQueryAnnotation().map(org.springframework.data.cassandra.repository.Query::allowFiltering) - .orElse(false)) { - + if (allowsFiltering()) { query = query.withAllowFiltering(); } @@ -175,11 +170,18 @@ class QueryStatementCreator { } return function.apply(query); - } catch (RuntimeException e) { - throw QueryCreationException.create(queryMethod, e); + } catch (RuntimeException cause) { + throw QueryCreationException.create(this.queryMethod, cause); } } + private boolean allowsFiltering() { + + return this.queryMethod.getQueryAnnotation() + .map(org.springframework.data.cassandra.repository.Query::allowFiltering) + .orElse(false); + } + /** * Create a {@link Statement} from a {@link StringBasedQuery} and apply query options. * @@ -199,7 +201,8 @@ class QueryStatementCreator { if (queryOptions.isPresent()) { queryToUse = Optional.ofNullable(parameterAccessor.getQueryOptions()) - .map(it -> QueryOptionsUtil.addQueryOptions(boundQuery, it)).orElse(boundQuery); + .map(it -> QueryOptionsUtil.addQueryOptions(boundQuery, it)) + .orElse(boundQuery); } else if (this.queryMethod.hasConsistencyLevel()) { queryToUse.setConsistencyLevel(this.queryMethod.getRequiredAnnotatedConsistencyLevel()); } @@ -209,8 +212,8 @@ class QueryStatementCreator { } return queryToUse; - } catch (RuntimeException e) { - throw QueryCreationException.create(this.queryMethod, e); + } catch (RuntimeException cause) { + throw QueryCreationException.create(this.queryMethod, cause); } } } diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/ReactiveCassandraQueryExecution.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/ReactiveCassandraQueryExecution.java index 0d1bc8d42..38f8b3b9a 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/ReactiveCassandraQueryExecution.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/ReactiveCassandraQueryExecution.java @@ -15,11 +15,12 @@ */ package org.springframework.data.cassandra.repository.query; +import java.util.List; + import lombok.NonNull; import lombok.RequiredArgsConstructor; -import reactor.core.publisher.Mono; -import java.util.List; +import reactor.core.publisher.Mono; import org.springframework.core.convert.converter.Converter; import org.springframework.data.cassandra.core.ReactiveCassandraOperations; @@ -103,7 +104,7 @@ interface ReactiveCassandraQueryExecution { @Override public Object execute(Statement statement, Class type) { - Mono> rows = operations.getReactiveCqlOperations().queryForRows(statement).buffer(2).next(); + Mono> rows = this.operations.getReactiveCqlOperations().queryForRows(statement).buffer(2).next(); return rows.map(it -> { @@ -115,9 +116,10 @@ interface ReactiveCassandraQueryExecution { Row row = it.get(0); - if (ProjectionUtil.isCountProjection(row)) { + if (ProjectionUtil.qualifiesAsCountProjection(row)) { Object object = row.getObject(0); + return ((Number) object).longValue() > 0; } } diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/ReactivePartTreeCassandraQuery.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/ReactivePartTreeCassandraQuery.java index c999d2576..cf83fe409 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/ReactivePartTreeCassandraQuery.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/ReactivePartTreeCassandraQuery.java @@ -112,7 +112,7 @@ public class ReactivePartTreeCassandraQuery extends AbstractReactiveCassandraQue */ @Override protected boolean isCountQuery() { - return tree.isCountProjection(); + return getTree().isCountProjection(); } /* (non-Javadoc) @@ -120,6 +120,6 @@ public class ReactivePartTreeCassandraQuery extends AbstractReactiveCassandraQue */ @Override protected boolean isExistsQuery() { - return tree.isExistsProjection(); + return getTree().isExistsProjection(); } } diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/ReactiveStringBasedCassandraQuery.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/ReactiveStringBasedCassandraQuery.java index 5eec08c9d..e7d77b3b5 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/ReactiveStringBasedCassandraQuery.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/ReactiveStringBasedCassandraQuery.java @@ -59,7 +59,8 @@ public class ReactiveStringBasedCassandraQuery extends AbstractReactiveCassandra ReactiveCassandraOperations operations, SpelExpressionParser expressionParser, EvaluationContextProvider evaluationContextProvider) { - this(queryMethod.getRequiredAnnotatedQuery(), queryMethod, operations, expressionParser, evaluationContextProvider); + this(queryMethod.getRequiredAnnotatedQuery(), queryMethod, operations, expressionParser, + evaluationContextProvider); } /** @@ -94,7 +95,6 @@ public class ReactiveStringBasedCassandraQuery extends AbstractReactiveCassandra throw new IllegalArgumentException(String.format(COUNT_AND_EXISTS, method)); } } else { - this.isCountQuery = false; this.isExistsQuery = false; } @@ -117,7 +117,7 @@ public class ReactiveStringBasedCassandraQuery extends AbstractReactiveCassandra */ @Override protected boolean isCountQuery() { - return isCountQuery; + return this.isCountQuery; } /* (non-Javadoc) @@ -125,6 +125,6 @@ public class ReactiveStringBasedCassandraQuery extends AbstractReactiveCassandra */ @Override protected boolean isExistsQuery() { - return isExistsQuery; + return this.isExistsQuery; } } diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/StringBasedCassandraQuery.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/StringBasedCassandraQuery.java index ed8513dd9..591b11337 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/StringBasedCassandraQuery.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/StringBasedCassandraQuery.java @@ -57,7 +57,8 @@ public class StringBasedCassandraQuery extends AbstractCassandraQuery { public StringBasedCassandraQuery(CassandraQueryMethod queryMethod, CassandraOperations operations, SpelExpressionParser expressionParser, EvaluationContextProvider evaluationContextProvider) { - this(queryMethod.getRequiredAnnotatedQuery(), queryMethod, operations, expressionParser, evaluationContextProvider); + this(queryMethod.getRequiredAnnotatedQuery(), queryMethod, operations, expressionParser, + evaluationContextProvider); } /** @@ -90,7 +91,6 @@ public class StringBasedCassandraQuery extends AbstractCassandraQuery { throw new IllegalArgumentException(String.format(COUNT_AND_EXISTS, method)); } } else { - this.isCountQuery = false; this.isExistsQuery = false; } @@ -113,7 +113,7 @@ public class StringBasedCassandraQuery extends AbstractCassandraQuery { */ @Override protected boolean isCountQuery() { - return isCountQuery; + return this.isCountQuery; } /* (non-Javadoc) @@ -121,6 +121,6 @@ public class StringBasedCassandraQuery extends AbstractCassandraQuery { */ @Override protected boolean isExistsQuery() { - return isExistsQuery; + return this.isExistsQuery; } } diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/AsyncCassandraTemplateIntegrationTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/AsyncCassandraTemplateIntegrationTests.java index 4c890c5c9..68e93332b 100644 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/AsyncCassandraTemplateIntegrationTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/AsyncCassandraTemplateIntegrationTests.java @@ -15,8 +15,8 @@ */ package org.springframework.data.cassandra.core; -import static org.assertj.core.api.Assertions.*; -import static org.springframework.data.cassandra.core.query.Criteria.*; +import static org.assertj.core.api.Assertions.assertThat; +import static org.springframework.data.cassandra.core.query.Criteria.where; import java.util.HashSet; import java.util.LinkedHashSet; @@ -25,6 +25,7 @@ import java.util.concurrent.Future; import org.junit.Before; import org.junit.Test; + import org.springframework.data.cassandra.core.convert.MappingCassandraConverter; import org.springframework.data.cassandra.core.cql.AsyncCqlTemplate; import org.springframework.data.cassandra.core.query.CassandraPageRequest; diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/CassandraTemplateIntegrationTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/CassandraTemplateIntegrationTests.java index 7073ab9bb..f9fda3f41 100644 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/CassandraTemplateIntegrationTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/CassandraTemplateIntegrationTests.java @@ -15,9 +15,9 @@ */ package org.springframework.data.cassandra.core; -import static org.assertj.core.api.Assertions.*; -import static org.junit.Assume.*; -import static org.springframework.data.cassandra.core.query.Criteria.*; +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assume.assumeTrue; +import static org.springframework.data.cassandra.core.query.Criteria.where; import java.util.Arrays; import java.util.Collections; @@ -30,6 +30,7 @@ import java.util.stream.Stream; import org.junit.Before; import org.junit.Test; + import org.springframework.data.cassandra.core.convert.MappingCassandraConverter; import org.springframework.data.cassandra.core.cql.CqlTemplate; import org.springframework.data.cassandra.core.mapping.BasicMapId; diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/CassandraTemplateUnitTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/CassandraTemplateUnitTests.java index 7a6069034..716ccdfb2 100644 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/CassandraTemplateUnitTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/CassandraTemplateUnitTests.java @@ -15,11 +15,14 @@ */ package org.springframework.data.cassandra.core; -import static org.assertj.core.api.Assertions.*; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.fail; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.*; +import static org.mockito.Mockito.reset; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; import java.util.Collections; import java.util.List; @@ -33,6 +36,7 @@ import org.mockito.Captor; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.junit.MockitoJUnitRunner; + import org.springframework.data.cassandra.CassandraConnectionFailureException; import org.springframework.data.cassandra.core.query.Query; import org.springframework.data.cassandra.domain.User; diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/ReactiveCassandraTemplateIntegrationTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/ReactiveCassandraTemplateIntegrationTests.java index 4601d9774..e0fdce7e4 100644 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/ReactiveCassandraTemplateIntegrationTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/ReactiveCassandraTemplateIntegrationTests.java @@ -15,8 +15,8 @@ */ package org.springframework.data.cassandra.core; -import static org.assertj.core.api.Assertions.*; -import static org.springframework.data.cassandra.core.query.Criteria.*; +import static org.assertj.core.api.Assertions.assertThat; +import static org.springframework.data.cassandra.core.query.Criteria.where; import reactor.core.publisher.Mono; import reactor.core.scheduler.Schedulers; @@ -25,6 +25,7 @@ import reactor.test.StepVerifier.FirstStep; import org.junit.Before; import org.junit.Test; + import org.springframework.data.cassandra.core.convert.MappingCassandraConverter; import org.springframework.data.cassandra.core.cql.ReactiveCqlTemplate; import org.springframework.data.cassandra.core.cql.session.DefaultBridgedReactiveSession; diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/ReactiveCassandraTemplateUnitTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/ReactiveCassandraTemplateUnitTests.java index 82bc1379f..8295481dc 100644 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/ReactiveCassandraTemplateUnitTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/ReactiveCassandraTemplateUnitTests.java @@ -15,18 +15,20 @@ */ package org.springframework.data.cassandra.core; -import static org.assertj.core.api.Assertions.*; +import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.*; +import static org.mockito.Mockito.reset; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import java.util.Collections; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import reactor.test.StepVerifier; -import java.util.Collections; - import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -34,6 +36,7 @@ import org.mockito.ArgumentCaptor; import org.mockito.Captor; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; + import org.springframework.data.cassandra.ReactiveResultSet; import org.springframework.data.cassandra.ReactiveSession; import org.springframework.data.cassandra.core.query.Query; diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/StatementFactoryUnitTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/StatementFactoryUnitTests.java index 618902530..482972be0 100644 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/StatementFactoryUnitTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/StatementFactoryUnitTests.java @@ -15,13 +15,14 @@ */ package org.springframework.data.cassandra.core; -import static org.assertj.core.api.Assertions.*; +import static org.assertj.core.api.Assertions.assertThat; import java.util.List; import java.util.Map; import java.util.Set; import org.junit.Test; + import org.springframework.data.annotation.Id; import org.springframework.data.cassandra.core.convert.CassandraConverter; import org.springframework.data.cassandra.core.convert.MappingCassandraConverter; diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/repository/QueryDerivationIntegrationTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/repository/QueryDerivationIntegrationTests.java index fbfcec478..35a06a695 100644 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/repository/QueryDerivationIntegrationTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/repository/QueryDerivationIntegrationTests.java @@ -15,8 +15,8 @@ */ package org.springframework.data.cassandra.repository; -import static org.assertj.core.api.Assertions.*; -import static org.junit.Assume.*; +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assume.assumeTrue; import java.time.LocalDate; import java.util.ArrayList; @@ -26,10 +26,10 @@ import java.util.Collections; import java.util.List; import java.util.Set; -import org.assertj.core.api.Assertions; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.ComponentScan.Filter; import org.springframework.context.annotation.Configuration; @@ -55,6 +55,8 @@ import org.springframework.data.util.Version; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.assertj.core.api.Assertions; + import com.datastax.driver.core.Session; /** diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/repository/ReactiveCassandraRepositoryIntegrationTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/repository/ReactiveCassandraRepositoryIntegrationTests.java index c7449eed3..931504389 100644 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/repository/ReactiveCassandraRepositoryIntegrationTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/repository/ReactiveCassandraRepositoryIntegrationTests.java @@ -15,17 +15,18 @@ */ package org.springframework.data.cassandra.repository; -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; -import reactor.test.StepVerifier; - import java.util.Arrays; import java.util.HashSet; import java.util.Set; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; +import reactor.test.StepVerifier; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; + import org.reactivestreams.Publisher; import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanClassLoaderAware; diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/repository/isolated/RepositoryReturnTypesIntegrationTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/repository/isolated/RepositoryReturnTypesIntegrationTests.java index ef0b020ea..3a39afca4 100755 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/repository/isolated/RepositoryReturnTypesIntegrationTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/repository/isolated/RepositoryReturnTypesIntegrationTests.java @@ -15,7 +15,8 @@ */ package org.springframework.data.cassandra.repository.isolated; -import static org.assertj.core.api.Assertions.*; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.offset; import java.math.BigDecimal; import java.math.BigInteger; @@ -31,6 +32,7 @@ import java.util.Set; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.data.cassandra.config.SchemaAction; diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/repository/query/PartTreeCassandraQueryUnitTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/repository/query/PartTreeCassandraQueryUnitTests.java index 2a5c96c12..c58c05f0d 100644 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/repository/query/PartTreeCassandraQueryUnitTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/repository/query/PartTreeCassandraQueryUnitTests.java @@ -15,8 +15,8 @@ */ package org.springframework.data.cassandra.repository.query; -import static org.assertj.core.api.Assertions.*; -import static org.mockito.Mockito.*; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.when; import java.lang.reflect.Method; import java.util.Arrays; @@ -30,6 +30,7 @@ import org.junit.rules.ExpectedException; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; + import org.springframework.data.cassandra.core.CassandraOperations; import org.springframework.data.cassandra.core.convert.CassandraConverter; import org.springframework.data.cassandra.core.convert.MappingCassandraConverter; diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/repository/query/ReactivePartTreeCassandraQueryUnitTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/repository/query/ReactivePartTreeCassandraQueryUnitTests.java index 425a10271..4418b599e 100644 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/repository/query/ReactivePartTreeCassandraQueryUnitTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/repository/query/ReactivePartTreeCassandraQueryUnitTests.java @@ -15,16 +15,15 @@ */ package org.springframework.data.cassandra.repository.query; -import static org.assertj.core.api.Assertions.*; -import static org.mockito.Mockito.*; - -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; -import rx.Single; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.when; import java.lang.reflect.Method; import java.util.Arrays; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + import org.junit.Before; import org.junit.Rule; import org.junit.Test; @@ -32,6 +31,7 @@ import org.junit.rules.ExpectedException; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; + import org.springframework.data.cassandra.core.ReactiveCassandraOperations; import org.springframework.data.cassandra.core.convert.MappingCassandraConverter; import org.springframework.data.cassandra.core.cql.QueryOptions; @@ -49,6 +49,8 @@ import org.springframework.util.ClassUtils; import com.datastax.driver.core.ConsistencyLevel; import com.datastax.driver.core.Statement; +import rx.Single; + /** * Unit tests for {@link ReactivePartTreeCassandraQuery}. * diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/repository/query/ReactiveStringBasedCassandraQueryUnitTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/repository/query/ReactiveStringBasedCassandraQueryUnitTests.java index bcae29e9c..5c8899711 100644 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/repository/query/ReactiveStringBasedCassandraQueryUnitTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/repository/query/ReactiveStringBasedCassandraQueryUnitTests.java @@ -15,8 +15,8 @@ */ package org.springframework.data.cassandra.repository.query; -import static org.assertj.core.api.Assertions.*; -import static org.mockito.Mockito.*; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.when; import java.lang.reflect.Method; @@ -25,6 +25,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; + import org.springframework.data.cassandra.ReactiveSession; import org.springframework.data.cassandra.core.ReactiveCassandraOperations; import org.springframework.data.cassandra.core.convert.MappingCassandraConverter;