diff --git a/spring-cql/src/main/java/org/springframework/cassandra/core/keyspace/TableSpecification.java b/spring-cql/src/main/java/org/springframework/cassandra/core/keyspace/TableSpecification.java index 6ac250cfa..02684f73a 100644 --- a/spring-cql/src/main/java/org/springframework/cassandra/core/keyspace/TableSpecification.java +++ b/spring-cql/src/main/java/org/springframework/cassandra/core/keyspace/TableSpecification.java @@ -1,12 +1,12 @@ /* - * Copyright 2013-2014 the original author or authors. - * + * Copyright 2013-2017 the original author or authors. + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -15,26 +15,28 @@ */ package org.springframework.cassandra.core.keyspace; -import static org.springframework.cassandra.core.PrimaryKeyType.CLUSTERED; -import static org.springframework.cassandra.core.PrimaryKeyType.PARTITIONED; -import static org.springframework.cassandra.core.cql.CqlIdentifier.cqlId; +import static org.springframework.cassandra.core.PrimaryKeyType.*; +import static org.springframework.cassandra.core.cql.CqlIdentifier.*; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Optional; import org.springframework.cassandra.core.Ordering; import org.springframework.cassandra.core.PrimaryKeyType; import org.springframework.cassandra.core.cql.CqlIdentifier; +import org.springframework.util.Assert; import com.datastax.driver.core.DataType; /** * Builder class to support the construction of table specifications that have columns. This class can also be used as a * standalone {@link TableDescriptor}, independent of {@link CreateTableSpecification}. - * + * * @author Matthew T. Adams * @author Alex Shvid + * @author Mark Paluch */ public class TableSpecification extends TableOptionsSpecification> implements TableDescriptor { @@ -60,97 +62,188 @@ public class TableSpecification extends TableOptionsSpecificationnull meaning ascending). Must - * be specified after all partition key columns and before any non-key columns. - * - * @param name The column name; must be a valid unquoted or quoted identifier without the surrounding double quotes. - * @param type The data type of the column. + * Adds the given primary key column to the table with ascending ordering. Must be specified after all partition key + * columns and before any non-key columns. + * + * @param name The column name; must be a valid unquoted or quoted identifier without the surrounding double quotes, + * must not be {@literal null}. + * @param type The data type of the column, must not be {@literal null}. * @return this */ - public T clusteredKeyColumn(String name, DataType type, Ordering ordering) { - return clusteredKeyColumn(cqlId(name), type, ordering); + public T clusteredKeyColumn(CqlIdentifier name, DataType type) { + return clusteredKeyColumn(name, type, Optional.empty()); } + /** + * Adds the given primary key column to the table with ascending ordering. Must be specified after all partition key + * columns and before any non-key columns. + * + * @param name The column name; must be a valid unquoted or quoted identifier without the surrounding double quotes, + * must not be {@literal null}. + * @param type The data type of the column, must not be {@literal null}. + * @param ordering The data type of the column, must not be {@literal null}. + * @return this + */ public T clusteredKeyColumn(CqlIdentifier name, DataType type, Ordering ordering) { - return column(name, type, CLUSTERED, ordering); + + Assert.notNull(ordering, "Ordering must not be null"); + return column(name, type, Optional.of(CLUSTERED), Optional.of(ordering)); + } + + /** + * Adds the given primary key column to the table with ascending ordering. Must be specified after all partition key + * columns and before any non-key columns. + * + * @param name The column name; must be a valid unquoted or quoted identifier without the surrounding double quotes, + * must not be {@literal null}. + * @param type The data type of the column, must not be {@literal null}. + * @param ordering The data type of the column, must not be {@literal null}. + * @return this + */ + public T clusteredKeyColumn(CqlIdentifier name, DataType type, Optional ordering) { + return column(name, type, Optional.of(CLUSTERED), ordering); } /** * Adds the given info as a new column to the table. Partition key columns must precede primary key columns, which * must precede non-key columns. - * - * @param name The column name; must be a valid unquoted or quoted identifier without the surrounding double quotes. - * @param type The data type of the column. - * @param keyType Indicates key type. Null means that the column is not a key column. + * + * @param name The column name; must be a valid unquoted or quoted identifier without the surrounding double quotes, + * must not be {@literal null}. + * @param type The data type of the column, must not be {@literal null}. + * @param keyType Indicates key type. Null means that the column is not a key column, must not be {@literal null}. + * @return this + */ + protected T column(String name, DataType type, PrimaryKeyType keyType) { + return column(name, type, keyType, Optional.empty()); + } + + /** + * Adds the given info as a new column to the table. Partition key columns must precede primary key columns, which + * must precede non-key columns. + * + * @param name The column name; must be a valid unquoted or quoted identifier without the surrounding double quotes, + * must not be {@literal null}. + * @param type The data type of the column, must not be {@literal null}. + * @param keyType Indicates key type, must not be {@literal null}. * @param ordering If the given {@link PrimaryKeyType} is {@link PrimaryKeyType#CLUSTERED}, then the given ordering is - * used, else ignored. + * used, else ignored, must not be {@literal null}. * @return this */ protected T column(String name, DataType type, PrimaryKeyType keyType, Ordering ordering) { - return column(cqlId(name), type, keyType, ordering); + + Assert.notNull(keyType, "PrimaryKeyType must not be null"); + Assert.notNull(ordering, "Ordering must not be null"); + + return column(cqlId(name), type, Optional.of(keyType), Optional.of(ordering)); + } + + /** + * Adds the given info as a new column to the table. Partition key columns must precede primary key columns, which + * must precede non-key columns. + * + * @param name The column name; must be a valid unquoted or quoted identifier without the surrounding double quotes, + * must not be {@literal null}. + * @param type The data type of the column, must not be {@literal null}. + * @param keyType Indicates key type, must not be {@literal null}. + * @param ordering If the given {@link PrimaryKeyType} is {@link PrimaryKeyType#CLUSTERED}, then the given ordering is + * used, else ignored, must not be {@literal null}. + * @return this + */ + protected T column(String name, DataType type, PrimaryKeyType keyType, Optional ordering) { + + Assert.notNull(keyType, "PrimaryKeyType must not be null"); + Assert.notNull(ordering, "Ordering must not be null"); + + return column(cqlId(name), type, Optional.of(keyType), ordering); } @SuppressWarnings("unchecked") - protected T column(CqlIdentifier name, DataType type, PrimaryKeyType keyType, Ordering ordering) { + protected T column(CqlIdentifier name, DataType type, Optional optionalKeyType, + Optional optionalOrdering) { - ColumnSpecification column = new ColumnSpecification().name(name).type(type).keyType(keyType) - .ordering(keyType == CLUSTERED ? ordering : null); + Assert.notNull(name, "Name must not be null"); + Assert.notNull(type, "DataType must not be null"); + Assert.notNull(optionalKeyType, "PrimaryKeyType must not be null"); + Assert.notNull(optionalOrdering, "Ordering must not be null"); + ColumnSpecification column = new ColumnSpecification().name(name).type(type); + + optionalKeyType.ifPresent(keyType -> { + column.keyType(keyType); + optionalOrdering.filter(o -> keyType == CLUSTERED).ifPresent(column::ordering); + + if (keyType == PrimaryKeyType.PARTITIONED) { + partitionKeyColumns.add(column); + } + + if (keyType == PrimaryKeyType.CLUSTERED) { + clusteredKeyColumns.add(column); + } + } + + ); columns.add(column); - if (keyType == PrimaryKeyType.PARTITIONED) { - partitionKeyColumns.add(column); - } - - if (keyType == PrimaryKeyType.CLUSTERED) { - clusteredKeyColumns.add(column); - } - - if (keyType == null) { + if (!optionalKeyType.isPresent()) { nonKeyColumns.add(column); } diff --git a/spring-cql/src/test/java/org/springframework/cassandra/core/AsyncCqlTemplateIntegrationTests.java b/spring-cql/src/test/java/org/springframework/cassandra/core/AsyncCqlTemplateIntegrationTests.java index 18e710b04..d7006e677 100644 --- a/spring-cql/src/test/java/org/springframework/cassandra/core/AsyncCqlTemplateIntegrationTests.java +++ b/spring-cql/src/test/java/org/springframework/cassandra/core/AsyncCqlTemplateIntegrationTests.java @@ -20,6 +20,7 @@ import static org.assertj.core.api.Assertions.*; import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.concurrent.Future; import java.util.concurrent.atomic.AtomicBoolean; import org.junit.Before; @@ -57,7 +58,7 @@ public class AsyncCqlTemplateIntegrationTests extends AbstractKeyspaceCreatingIn @Test // DATACASS-292 public void executeShouldRemoveRecords() throws Exception { - template.execute("DELETE FROM user WHERE id = 'WHITE'").get(); + getUninterruptibly(template.execute("DELETE FROM user WHERE id = 'WHITE'")); assertThat(session.execute("SELECT * FROM user").one()).isNull(); } @@ -66,9 +67,9 @@ public class AsyncCqlTemplateIntegrationTests extends AbstractKeyspaceCreatingIn public void queryShouldInvokeCallback() throws Exception { List result = new ArrayList<>(); - template.query("SELECT id FROM user;", row -> { + getUninterruptibly(template.query("SELECT id FROM user;", row -> { result.add(row.getString(0)); - }).get(); + })); assertThat(result).contains("WHITE"); } @@ -76,7 +77,7 @@ public class AsyncCqlTemplateIntegrationTests extends AbstractKeyspaceCreatingIn @Test // DATACASS-292 public void queryForObjectShouldReturnFirstColumn() throws Exception { - String id = template.queryForObject("SELECT id FROM user;", String.class).get(); + String id = getUninterruptibly(template.queryForObject("SELECT id FROM user;", String.class)); assertThat(id).isEqualTo("WHITE"); } @@ -84,7 +85,7 @@ public class AsyncCqlTemplateIntegrationTests extends AbstractKeyspaceCreatingIn @Test // DATACASS-292 public void queryForObjectShouldReturnMap() throws Exception { - Map map = template.queryForMap("SELECT * FROM user;").get(); + Map map = getUninterruptibly(template.queryForMap("SELECT * FROM user;")); assertThat(map).containsEntry("id", "WHITE").containsEntry("username", "Walter"); } @@ -92,7 +93,7 @@ public class AsyncCqlTemplateIntegrationTests extends AbstractKeyspaceCreatingIn @Test // DATACASS-292 public void executeStatementShouldRemoveRecords() throws Exception { - template.execute(QueryBuilder.delete().from("user").where(QueryBuilder.eq("id", "WHITE"))).get(); + getUninterruptibly(template.execute(QueryBuilder.delete().from("user").where(QueryBuilder.eq("id", "WHITE")))); assertThat(session.execute("SELECT * FROM user").one()).isNull(); } @@ -101,9 +102,9 @@ public class AsyncCqlTemplateIntegrationTests extends AbstractKeyspaceCreatingIn public void queryStatementShouldInvokeCallback() throws Exception { List result = new ArrayList<>(); - template.query(QueryBuilder.select("id").from("user"), row -> { + getUninterruptibly(template.query(QueryBuilder.select("id").from("user"), row -> { result.add(row.getString(0)); - }).get(); + })); assertThat(result).contains("WHITE"); } @@ -111,7 +112,7 @@ public class AsyncCqlTemplateIntegrationTests extends AbstractKeyspaceCreatingIn @Test // DATACASS-292 public void queryForObjectStatementShouldReturnFirstColumn() throws Exception { - String id = template.queryForObject(QueryBuilder.select("id").from("user"), String.class).get(); + String id = getUninterruptibly(template.queryForObject(QueryBuilder.select("id").from("user"), String.class)); assertThat(id).isEqualTo("WHITE"); } @@ -119,7 +120,7 @@ public class AsyncCqlTemplateIntegrationTests extends AbstractKeyspaceCreatingIn @Test // DATACASS-292 public void queryForObjectStatementShouldReturnMap() throws Exception { - Map map = template.queryForMap(QueryBuilder.select().from("user")).get(); + Map map = getUninterruptibly(template.queryForMap(QueryBuilder.select().from("user"))); assertThat(map).containsEntry("id", "WHITE").containsEntry("username", "Walter"); } @@ -127,7 +128,7 @@ public class AsyncCqlTemplateIntegrationTests extends AbstractKeyspaceCreatingIn @Test // DATACASS-292 public void executeWithArgsShouldRemoveRecords() throws Exception { - template.execute("DELETE FROM user WHERE id = ?", "WHITE").get(); + getUninterruptibly(template.execute("DELETE FROM user WHERE id = ?", "WHITE")); assertThat(session.execute("SELECT * FROM user").one()).isNull(); } @@ -136,9 +137,9 @@ public class AsyncCqlTemplateIntegrationTests extends AbstractKeyspaceCreatingIn public void queryPreparedStatementShouldInvokeCallback() throws Exception { List result = new ArrayList<>(); - template.query("SELECT id FROM user WHERE id = ?;", row -> { + getUninterruptibly(template.query("SELECT id FROM user WHERE id = ?;", row -> { result.add(row.getString(0)); - }, "WHITE").get(); + }, "WHITE")); assertThat(result).contains("WHITE"); } @@ -147,12 +148,12 @@ public class AsyncCqlTemplateIntegrationTests extends AbstractKeyspaceCreatingIn public void queryPreparedStatementCreatorShouldInvokeCallback() throws Exception { List result = new ArrayList<>(); - template.query( + getUninterruptibly(template.query( session -> new GuavaListenableFutureAdapter( session.prepareAsync("SELECT id FROM user WHERE id = ?;"), template.getExceptionTranslator()), ps -> ps.bind("WHITE"), row -> { result.add(row.getString(0)); - }).get(); + })); assertThat(result).contains("WHITE"); } @@ -160,7 +161,7 @@ public class AsyncCqlTemplateIntegrationTests extends AbstractKeyspaceCreatingIn @Test // DATACASS-292 public void queryForObjectWithArgsShouldReturnFirstColumn() throws Exception { - String id = template.queryForObject("SELECT id FROM user WHERE id = ?;", String.class, "WHITE").get(); + String id = getUninterruptibly(template.queryForObject("SELECT id FROM user WHERE id = ?;", String.class, "WHITE")); assertThat(id).isEqualTo("WHITE"); } @@ -168,8 +169,17 @@ public class AsyncCqlTemplateIntegrationTests extends AbstractKeyspaceCreatingIn @Test // DATACASS-292 public void queryForObjectWithArgsShouldReturnMap() throws Exception { - Map map = template.queryForMap("SELECT * FROM user WHERE id = ?;", "WHITE").get(); + Map map = getUninterruptibly(template.queryForMap("SELECT * FROM user WHERE id = ?;", "WHITE")); assertThat(map).containsEntry("id", "WHITE").containsEntry("username", "Walter"); } + + private static T getUninterruptibly(Future future) { + + try { + return future.get(); + } catch (Exception e) { + throw new IllegalStateException(e); + } + } } diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/convert/BasicCassandraRowValueProvider.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/convert/BasicCassandraRowValueProvider.java index 16367c6aa..8cd2cc26d 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/convert/BasicCassandraRowValueProvider.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/convert/BasicCassandraRowValueProvider.java @@ -15,6 +15,8 @@ */ package org.springframework.data.cassandra.convert; +import java.util.Optional; + import org.springframework.data.cassandra.mapping.CassandraPersistentProperty; import org.springframework.data.mapping.model.DefaultSpELExpressionEvaluator; import org.springframework.data.mapping.model.SpELExpressionEvaluator; @@ -57,14 +59,14 @@ public class BasicCassandraRowValueProvider implements CassandraRowValueProvider */ @Override @SuppressWarnings("unchecked") - public Object getPropertyValue(CassandraPersistentProperty property) { + public Optional getPropertyValue(CassandraPersistentProperty property) { - String expression = property.getSpelExpression(); - if (expression != null) { - return evaluator.evaluate(expression); + Optional spelExpression = property.getSpelExpression(); + if (spelExpression.isPresent()) { + return spelExpression.flatMap(s -> Optional.ofNullable(evaluator.evaluate(s))); } - return reader.get(property.getColumnName()); + return Optional.ofNullable((T) reader.get(property.getColumnName())); } /* (non-Javadoc) diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/convert/CassandraConverter.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/convert/CassandraConverter.java index 6c990e58c..81e1f0b55 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/convert/CassandraConverter.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/convert/CassandraConverter.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2014 the original author or authors + * Copyright 2013-2017 the original author or authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ */ package org.springframework.data.cassandra.convert; +import java.util.Optional; + import org.springframework.data.cassandra.mapping.CassandraMappingContext; import org.springframework.data.cassandra.mapping.CassandraPersistentEntity; import org.springframework.data.cassandra.mapping.CassandraPersistentProperty; @@ -66,12 +68,12 @@ public interface CassandraConverter /** * Converts the given object into one Cassandra will be able to store natively in a column. * - * @param obj {@link Object} to convert; can be {@literal null}. + * @param obj {@link Object} to convert, must not be {@literal null}. * @param typeInformation {@link TypeInformation} used to describe the object type; must not be {@literal null}. * @return the result of the conversion. * @since 1.5 */ - Object convertToCassandraColumn(Object obj, TypeInformation typeInformation); + Optional convertToCassandraColumn(Optional obj, TypeInformation typeInformation); /** * Returns the {@link CustomConversions} registered in the {@link CassandraConverter}. diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/convert/CassandraPersistentEntityParameterValueProvider.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/convert/CassandraPersistentEntityParameterValueProvider.java deleted file mode 100644 index 5dda0f439..000000000 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/convert/CassandraPersistentEntityParameterValueProvider.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 2013-2014 the original author or authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.data.cassandra.convert; - -import org.springframework.data.cassandra.mapping.CassandraPersistentProperty; -import org.springframework.data.mapping.PersistentEntity; -import org.springframework.data.mapping.model.PersistentEntityParameterValueProvider; -import org.springframework.data.mapping.model.PropertyValueProvider; - -public class CassandraPersistentEntityParameterValueProvider extends - PersistentEntityParameterValueProvider { - - public CassandraPersistentEntityParameterValueProvider(PersistentEntity entity, - PropertyValueProvider provider, Object parent) { - super(entity, provider, parent); - } -} diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/convert/CassandraUDTValueProvider.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/convert/CassandraUDTValueProvider.java index 4c39e4464..299c26923 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/convert/CassandraUDTValueProvider.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/convert/CassandraUDTValueProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 the original author or authors. + * Copyright 2016-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ */ package org.springframework.data.cassandra.convert; +import java.util.Optional; + import org.springframework.data.cassandra.mapping.CassandraPersistentProperty; import org.springframework.data.mapping.model.DefaultSpELExpressionEvaluator; import org.springframework.data.mapping.model.SpELExpressionEvaluator; @@ -62,18 +64,17 @@ public class CassandraUDTValueProvider implements CassandraValueProvider { * @see org.springframework.data.mapping.model.PropertyValueProvider#getPropertyValue(org.springframework.data.mapping.PersistentProperty) */ @SuppressWarnings("unchecked") - public Object getPropertyValue(CassandraPersistentProperty property) { + public Optional getPropertyValue(CassandraPersistentProperty property) { - String expression = property.getSpelExpression(); - - if (expression != null) { - return evaluator.evaluate(expression); + Optional spelExpression = property.getSpelExpression(); + if (spelExpression.isPresent()) { + return spelExpression.flatMap(s -> Optional.ofNullable(evaluator.evaluate(s))); } String name = property.getColumnName().toCql(); DataType fieldType = udtValue.getType().getFieldType(name); - return udtValue.get(name, codecRegistry.codecFor(fieldType)); + return Optional.ofNullable(udtValue.get(name, codecRegistry.codecFor(fieldType))); } /* (non-Javadoc) diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/convert/CustomConversions.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/convert/CustomConversions.java index 78c7810f2..7fb2606bb 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/convert/CustomConversions.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/convert/CustomConversions.java @@ -18,12 +18,12 @@ package org.springframework.data.cassandra.convert; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; -import java.util.HashSet; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; +import java.util.function.Supplier; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -40,7 +40,6 @@ import org.springframework.data.convert.ReadingConverter; import org.springframework.data.convert.ThreeTenBackPortConverters; import org.springframework.data.convert.WritingConverter; import org.springframework.data.mapping.model.SimpleTypeHolder; -import org.springframework.data.util.CacheValue; import org.springframework.util.Assert; /** @@ -60,20 +59,19 @@ public class CustomConversions { private final Set readingPairs; private final Set writingPairs; - private final Set> customSimpleTypes; private final CassandraSimpleTypeHolder simpleTypeHolder; private final List converters; - private final Map>> customReadTargetTypes; - private final Map>> customWriteTargetTypes; - private final Map, CacheValue>> rawWriteTargetTypes; + private final Map> customReadTargetTypes; + private final Map> customWriteTargetTypes; + private final Map, Class> rawWriteTargetTypes; /** * Creates an empty {@link CustomConversions} object. */ CustomConversions() { - this(new ArrayList()); + this(new ArrayList<>()); } /** @@ -85,12 +83,11 @@ public class CustomConversions { Assert.notNull(converters, "List of converters must not be null"); - this.readingPairs = new LinkedHashSet(); - this.writingPairs = new LinkedHashSet(); - this.customSimpleTypes = new HashSet>(); - this.customReadTargetTypes = new ConcurrentHashMap>>(); - this.customWriteTargetTypes = new ConcurrentHashMap>>(); - this.rawWriteTargetTypes = new ConcurrentHashMap, CacheValue>>(); + this.readingPairs = new LinkedHashSet<>(); + this.writingPairs = new LinkedHashSet<>(); + this.customReadTargetTypes = new ConcurrentHashMap<>(); + this.customWriteTargetTypes = new ConcurrentHashMap<>(); + this.rawWriteTargetTypes = new ConcurrentHashMap<>(); List toRegister = new ArrayList(); @@ -222,7 +219,6 @@ public class CustomConversions { if (converterRegistration.isWriting()) { writingPairs.add(pair); - customSimpleTypes.add(pair.getSourceType()); if (LOG.isWarnEnabled() && !converterRegistration.isSimpleTargetType()) { LOG.warn(String.format(WRITE_CONVERTER_NOT_SIMPLE, pair.getSourceType(), pair.getTargetType())); @@ -239,7 +235,7 @@ public class CustomConversions { */ public Class getCustomWriteTarget(final Class sourceType) { - return getOrCreateAndCache(sourceType, rawWriteTargetTypes, new Producer() { + return getOrCreateAndCache(sourceType, rawWriteTargetTypes, new Supplier>() { @Override public Class get() { @@ -264,13 +260,7 @@ public class CustomConversions { } return getOrCreateAndCache(new ConvertiblePair(sourceType, requestedTargetType), customWriteTargetTypes, - new Producer() { - - @Override - public Class get() { - return getCustomTarget(sourceType, requestedTargetType, writingPairs); - } - }); + () -> getCustomTarget(sourceType, requestedTargetType, writingPairs)); } /** @@ -322,13 +312,7 @@ public class CustomConversions { } return getOrCreateAndCache(new ConvertiblePair(sourceType, requestedTargetType), customReadTargetTypes, - new Producer() { - - @Override - public Class get() { - return getCustomTarget(sourceType, requestedTargetType, readingPairs); - } - }); + () -> getCustomTarget(sourceType, requestedTargetType, readingPairs)); } /** @@ -350,44 +334,23 @@ public class CustomConversions { return requestedTargetType; } - for (ConvertiblePair typePair : pairs) { - if (typePair.getSourceType().isAssignableFrom(sourceType)) { - Class targetType = typePair.getTargetType(); - - if (requestedTargetType == null || targetType.isAssignableFrom(requestedTargetType)) { - return targetType; - } - } - } - - return null; + return pairs.stream() // + .filter(typePair -> typePair.getSourceType().isAssignableFrom(sourceType)) // + .map(ConvertiblePair::getTargetType) // + .filter(targetType -> requestedTargetType == null || targetType.isAssignableFrom(requestedTargetType)) // + .findFirst().orElse(null); } /** - * Will try to find a value for the given key in the given cache or produce one using the given {@link Producer} and + * Will try to find a value for the given key in the given cache or produce one using the given {@link Supplier} and * store it in the cache. * * @param key the key to lookup a potentially existing value, must not be {@literal null}. * @param cache the cache to find the value in, must not be {@literal null}. - * @param producer the {@link Producer} to create values to cache, must not be {@literal null}. + * @param producer the {@link Supplier} to create values to cache, must not be {@literal null}. * @return */ - private static Class getOrCreateAndCache(T key, Map>> cache, Producer producer) { - - CacheValue> cacheValue = cache.get(key); - - if (cacheValue != null) { - return cacheValue.getValue(); - } - - Class type = producer.get(); - - cache.put(key, CacheValue.> ofNullable(type)); - - return type; - } - - private interface Producer { - Class get(); + private static Class getOrCreateAndCache(T key, Map> cache, Supplier> producer) { + return cache.computeIfAbsent(key, t -> producer.get()); } } diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/convert/MappingCassandraConverter.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/convert/MappingCassandraConverter.java index e4705f492..aabb5b982 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/convert/MappingCassandraConverter.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/convert/MappingCassandraConverter.java @@ -24,7 +24,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; -import java.util.Map.Entry; +import java.util.Optional; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -44,11 +44,11 @@ import org.springframework.data.cassandra.repository.MapId; import org.springframework.data.cassandra.repository.MapIdentifiable; import org.springframework.data.convert.EntityInstantiator; import org.springframework.data.mapping.PersistentPropertyAccessor; -import org.springframework.data.mapping.PropertyHandler; import org.springframework.data.mapping.context.MappingContext; import org.springframework.data.mapping.model.ConvertingPropertyAccessor; import org.springframework.data.mapping.model.DefaultSpELExpressionEvaluator; import org.springframework.data.mapping.model.MappingException; +import org.springframework.data.mapping.model.PersistentEntityParameterValueProvider; import org.springframework.data.mapping.model.PropertyValueProvider; import org.springframework.data.mapping.model.SpELContext; import org.springframework.data.util.ClassTypeInformation; @@ -141,11 +141,8 @@ public class MappingCassandraConverter extends AbstractCassandraConverter } CassandraPersistentEntity persistentEntity = (CassandraPersistentEntity) getMappingContext() - .getPersistentEntity(typeInfo); - if (persistentEntity == null) { - throw new MappingException(String.format("No mapping metadata found for %s", rawType.getName())); - } + .getRequiredPersistentEntity(typeInfo); return readEntityFromRow(persistentEntity, row); } @@ -164,8 +161,8 @@ public class MappingCassandraConverter extends AbstractCassandraConverter DefaultSpELExpressionEvaluator expressionEvaluator = new DefaultSpELExpressionEvaluator(row, spELContext); BasicCassandraRowValueProvider rowValueProvider = new BasicCassandraRowValueProvider(row, expressionEvaluator); - CassandraPersistentEntityParameterValueProvider parameterProvider = new CassandraPersistentEntityParameterValueProvider( - entity, new MappingAndConvertingValueProvider(rowValueProvider), null); + PersistentEntityParameterValueProvider parameterProvider = new PersistentEntityParameterValueProvider<>( + entity, new MappingAndConvertingValueProvider(rowValueProvider), Optional.empty()); EntityInstantiator instantiator = instantiators.getInstantiatorFor(entity); S instance = instantiator.createInstance(entity, parameterProvider); @@ -182,8 +179,8 @@ public class MappingCassandraConverter extends AbstractCassandraConverter CassandraUDTValueProvider valueProvider = new CassandraUDTValueProvider(udtValue, CodecRegistry.DEFAULT_INSTANCE, expressionEvaluator); - CassandraPersistentEntityParameterValueProvider parameterProvider = new CassandraPersistentEntityParameterValueProvider( - entity, new MappingAndConvertingValueProvider(valueProvider), null); + PersistentEntityParameterValueProvider parameterProvider = new PersistentEntityParameterValueProvider( + entity, new MappingAndConvertingValueProvider(valueProvider), Optional.empty()); EntityInstantiator instantiator = instantiators.getInstantiatorFor(entity); S instance = instantiator.createInstance(entity, parameterProvider); @@ -202,13 +199,8 @@ public class MappingCassandraConverter extends AbstractCassandraConverter protected void readProperties(final CassandraPersistentEntity entity, final CassandraValueProvider valueProvider, final PersistentPropertyAccessor propertyAccessor) { - entity.doWithProperties(new PropertyHandler() { - - @Override - public void doWithPersistentProperty(CassandraPersistentProperty property) { - MappingCassandraConverter.this.readProperty(entity, property, valueProvider, propertyAccessor); - } - }); + entity.getPersistentProperties().forEach( + property -> MappingCassandraConverter.this.readProperty(entity, property, valueProvider, propertyAccessor)); } /** @@ -231,20 +223,21 @@ public class MappingCassandraConverter extends AbstractCassandraConverter } if (property.isCompositePrimaryKey()) { - CassandraPersistentProperty keyProperty = entity.getIdProperty(); - CassandraPersistentEntity keyEntity = keyProperty.getCompositePrimaryKeyEntity(); - Object key = propertyAccessor.getProperty(keyProperty); + CassandraPersistentEntity keyEntity = property.getCompositePrimaryKeyEntity(); - if (key == null) { - key = instantiatePrimaryKey(keyEntity, keyProperty, valueProvider); + Optional optionalKey = propertyAccessor.getProperty(property); + + if (!optionalKey.isPresent()) { + optionalKey = Optional.of(instantiatePrimaryKey(keyEntity, property, valueProvider)); } // now recurse on using the key this time - readProperties(property.getCompositePrimaryKeyEntity(), valueProvider, getConvertingAccessor(key, keyEntity)); + optionalKey.ifPresent(key -> readProperties(property.getCompositePrimaryKeyEntity(), valueProvider, + getConvertingAccessor(key, keyEntity))); // now that the key's properties have been populated, set the key property on the entity - propertyAccessor.setProperty(keyProperty, key); + propertyAccessor.setProperty(property, optionalKey); return; } @@ -261,7 +254,7 @@ public class MappingCassandraConverter extends AbstractCassandraConverter PropertyValueProvider propertyProvider) { return instantiators.getInstantiatorFor(entity).createInstance(entity, - new CassandraPersistentEntityParameterValueProvider(entity, propertyProvider, null)); + new PersistentEntityParameterValueProvider<>(entity, propertyProvider, Optional.empty())); } /* (non-Javadoc) @@ -278,18 +271,21 @@ public class MappingCassandraConverter extends AbstractCassandraConverter } /* (non-Javadoc) - * @see org.springframework.data.cassandra.convert.CassandraConverter#convertToCassandraColumn(java.lang.Object, org.springframework.data.util.TypeInformation) + * @see org.springframework.data.cassandra.convert.CassandraConverter#convertToCassandraColumn(java.util.Optional, org.springframework.data.util.TypeInformation) */ @Override - public Object convertToCassandraColumn(Object obj, TypeInformation typeInformation) { + public Optional convertToCassandraColumn(Optional obj, TypeInformation typeInformation) { Assert.notNull(typeInformation, "TypeInformation must not be null!"); - if (obj == null || obj.getClass().isArray()) { - return obj; - } + return obj.flatMap(t -> { - return getWriteValue(obj, typeInformation); + if (t.getClass().isArray()) { + return Optional.of(t); + } + + return getWriteValue(obj, typeInformation); + }); } @Override @@ -297,7 +293,7 @@ public class MappingCassandraConverter extends AbstractCassandraConverter if (source != null) { Class beanClassLoaderClass = transformClassToBeanClassLoaderClass(source.getClass()); - CassandraPersistentEntity entity = getMappingContext().getPersistentEntity(beanClassLoaderClass); + CassandraPersistentEntity entity = getMappingContext().getRequiredPersistentEntity(beanClassLoaderClass); write(source, sink, entity); } @@ -336,34 +332,30 @@ public class MappingCassandraConverter extends AbstractCassandraConverter protected void writeInsertFromWrapper(final ConvertingPropertyAccessor accessor, final Insert insert, CassandraPersistentEntity entity) { - entity.doWithProperties(new PropertyHandler() { + entity.getPersistentProperties().forEach(property -> { - @Override - public void doWithPersistentProperty(CassandraPersistentProperty property) { + Optional value = getWriteValue(property, accessor); - Object value = getWriteValue(property, accessor); - - if (log.isDebugEnabled()) { - log.debug("doWithProperties Property.type {}, Property.value {}", property.getType().getName(), value); - } - - if (property.isCompositePrimaryKey()) { - if (log.isDebugEnabled()) { - log.debug("Property is a compositeKey"); - } - - writeInsertFromWrapper(getConvertingAccessor(value, property.getCompositePrimaryKeyEntity()), insert, - property.getCompositePrimaryKeyEntity()); - - return; - } - - if (log.isDebugEnabled()) { - log.debug("Adding insert.value [{}] - [{}]", property.getColumnName().toCql(), value); - } - - insert.value(property.getColumnName().toCql(), value); + if (log.isDebugEnabled()) { + log.debug("doWithProperties Property.type {}, Property.value {}", property.getType().getName(), value); } + + if (property.isCompositePrimaryKey()) { + if (log.isDebugEnabled()) { + log.debug("Property is a compositeKey"); + } + + writeInsertFromWrapper(getConvertingAccessor(value.orElse(null), property.getCompositePrimaryKeyEntity()), + insert, property.getCompositePrimaryKeyEntity()); + + return; + } + + if (log.isDebugEnabled()) { + log.debug("Adding insert.value [{}] - [{}]", property.getColumnName().toCql(), value); + } + + insert.value(property.getColumnName().toCql(), value.orElse(null)); }); } @@ -374,72 +366,53 @@ public class MappingCassandraConverter extends AbstractCassandraConverter protected void writeUpdateFromWrapper(final ConvertingPropertyAccessor accessor, final Update update, final CassandraPersistentEntity entity) { - entity.doWithProperties(new PropertyHandler() { + entity.getPersistentProperties().forEach(property -> { - @Override - public void doWithPersistentProperty(CassandraPersistentProperty property) { + Optional value = getWriteValue(property, accessor); - Object value = getWriteValue(property, accessor); + if (property.isCompositePrimaryKey()) { + CassandraPersistentEntity keyEntity = property.getCompositePrimaryKeyEntity(); + writeUpdateFromWrapper(getConvertingAccessor(value.orElse(null), keyEntity), update, keyEntity); + return; + } - if (property.isCompositePrimaryKey()) { - CassandraPersistentEntity keyEntity = property.getCompositePrimaryKeyEntity(); - writeUpdateFromWrapper(getConvertingAccessor(value, keyEntity), update, keyEntity); - return; - } - - if (isPrimaryKeyPart(property)) { - update.where(QueryBuilder.eq(property.getColumnName().toCql(), value)); - } else { - update.with(QueryBuilder.set(property.getColumnName().toCql(), value)); - } + if (isPrimaryKeyPart(property)) { + update.where(QueryBuilder.eq(property.getColumnName().toCql(), value.orElse(null))); + } else { + update.with(QueryBuilder.set(property.getColumnName().toCql(), value.orElse(null))); } }); } protected void writeSelectWhereFromObject(final Object object, final Select.Where where, CassandraPersistentEntity entity) { - - Collection clauses = getWhereClauses(object, entity); - - for (Clause clause : clauses) { - where.and(clause); - } + getWhereClauses(object, entity).forEach(where::and); } protected void writeDeleteWhereFromObject(final Object object, final Delete.Where where, CassandraPersistentEntity entity) { - - Collection clauses = getWhereClauses(object, entity); - - for (Clause clause : clauses) { - where.and(clause); - } + getWhereClauses(object, entity).forEach(where::and); } protected void writeUDTValueWhereFromObject(final ConvertingPropertyAccessor accessor, final UDTValue udtValue, CassandraPersistentEntity entity) { - entity.doWithProperties(new PropertyHandler() { + entity.getPersistentProperties().forEach(property -> { - @Override - public void doWithPersistentProperty(CassandraPersistentProperty property) { + Optional value = getWriteValue(property, accessor); - Object value = getWriteValue(property, accessor); - - if (log.isDebugEnabled()) { - log.debug("writeUDTValueWhereFromObject Property.type {}, Property.value {}", property.getType().getName(), - value); - } - - if (log.isDebugEnabled()) { - log.debug("Adding udt.value [{}] - [{}]", property.getColumnName().toCql(), value); - } - - TypeCodec typeCodec = CodecRegistry.DEFAULT_INSTANCE - .codecFor(getMappingContext().getDataType(property)); - - udtValue.set(property.getColumnName().toCql(), value, typeCodec); + if (log.isDebugEnabled()) { + log.debug("writeUDTValueWhereFromObject Property.type {}, Property.value {}", property.getType().getName(), + value); } + + if (log.isDebugEnabled()) { + log.debug("Adding udt.value [{}] - [{}]", property.getColumnName().toCql(), value); + } + + TypeCodec typeCodec = CodecRegistry.DEFAULT_INSTANCE.codecFor(getMappingContext().getDataType(property)); + + udtValue.set(property.getColumnName().toCql(), value.orElse(null), typeCodec); }); } @@ -447,38 +420,44 @@ public class MappingCassandraConverter extends AbstractCassandraConverter Assert.notNull(source, "Id source must not be null"); - CassandraPersistentProperty idProperty = entity.getIdProperty(); - Object id = extractId(source, entity); - Assert.notNull(id, String.format("No Id value found in object %s", source)); + Optional optionalIdProperty = entity.getIdProperty(); + + Optional optionalCompositeIdProperty = optionalIdProperty + .filter(CassandraPersistentProperty::isCompositePrimaryKey); + if (id instanceof MapId) { - return getWhereClauses((MapId) id, idProperty != null && idProperty.isCompositePrimaryKey() - ? idProperty.getCompositePrimaryKeyEntity() : entity); + + // FIXME: Generics + CassandraPersistentEntity whereEntity = optionalCompositeIdProperty // + .map(CassandraPersistentProperty::getCompositePrimaryKeyEntity) // + .orElse((CassandraPersistentEntity) entity); + + return getWhereClauses((MapId) id, whereEntity); } - if (idProperty == null) { - throw new InvalidDataAccessApiUsageException( - String.format("Cannot obtain where clauses for entity [%s] using [%s]", entity.getName(), source)); - } + CassandraPersistentProperty idProperty = optionalIdProperty + .orElseThrow(() -> new InvalidDataAccessApiUsageException( + String.format("Cannot obtain where clauses for entity [%s] using [%s]", entity.getName(), source))); - if (idProperty.isCompositePrimaryKey()) { + if (optionalCompositeIdProperty.isPresent()) { - if (ClassUtils.isAssignableValue(idProperty.getType(), id)) { - return getWhereClauses(getConvertingAccessor(id, idProperty.getCompositePrimaryKeyEntity()), - idProperty.getCompositePrimaryKeyEntity()); - } else { - throw new InvalidDataAccessApiUsageException( - String.format("Cannot use [%s] as composite Id for [%s]", id, entity.getName())); - } + CassandraPersistentProperty compositeIdProperty = optionalCompositeIdProperty + .filter(p -> ClassUtils.isAssignableValue(p.getType(), id)) + .orElseThrow(() -> new InvalidDataAccessApiUsageException( + String.format("Cannot use [%s] as composite Id for [%s]", id, entity.getName()))); + + return getWhereClauses(getConvertingAccessor(id, compositeIdProperty.getCompositePrimaryKeyEntity()), + compositeIdProperty.getCompositePrimaryKeyEntity()); } Class targetType = getTargetType(idProperty); if (getConversionService().canConvert(id.getClass(), targetType)) { - return Collections.singleton( - QueryBuilder.eq(idProperty.getColumnName().toCql(), getPotentiallyConvertedSimpleValue(id, targetType))); + return Collections.singleton(QueryBuilder.eq(idProperty.getColumnName().toCql(), + getPotentiallyConvertedSimpleValue(Optional.of(id), (Class) targetType).orElse(null))); } return Collections.singleton(QueryBuilder.eq(idProperty.getColumnName().toCql(), id)); @@ -503,16 +482,12 @@ public class MappingCassandraConverter extends AbstractCassandraConverter Assert.isTrue(entity.isCompositePrimaryKey(), String.format("Entity [%s] is not a composite primary key", entity.getName())); - final Collection clauses = new ArrayList(); + Collection clauses = new ArrayList<>(); - entity.doWithProperties(new PropertyHandler() { - - @Override - public void doWithPersistentProperty(CassandraPersistentProperty property) { - TypeCodec codec = getCodec(property); - Object value = accessor.getProperty(property, codec.getJavaType().getRawType()); - clauses.add(QueryBuilder.eq(property.getColumnName().toCql(), value)); - } + entity.getPersistentProperties().forEach(property -> { + TypeCodec codec = getCodec(property); + Optional value = accessor.getProperty(property, codec.getJavaType().getRawType()); + clauses.add(QueryBuilder.eq(property.getColumnName().toCql(), value.orElse(null))); }); return clauses; @@ -522,16 +497,19 @@ public class MappingCassandraConverter extends AbstractCassandraConverter Assert.notNull(id, "MapId must not be null"); - Collection clauses = new ArrayList(); + Collection clauses = new ArrayList<>(); for (Entry entry : id.entrySet()) { - CassandraPersistentProperty persistentProperty = entity.getPersistentProperty(entry.getKey()); - Assert.notNull(persistentProperty, String.format( - "MapId contains references [%s] that is an unknown property of [%s]", entry.getKey(), entity.getName())); + Optional lookup = entity.getPersistentProperty(entry.getKey()); - clauses.add(QueryBuilder.eq(persistentProperty.getColumnName().toCql(), - getWriteValue(entry.getValue(), persistentProperty.getTypeInformation()))); + CassandraPersistentProperty persistentProperty = lookup + .orElseThrow(() -> new IllegalArgumentException(String.format( + "MapId contains references [%s] that is an unknown property of [%s]", entry.getKey(), entity.getName()))); + + Optional writeValue = getWriteValue(Optional.ofNullable(entry.getValue()), + persistentProperty.getTypeInformation()); + clauses.add(QueryBuilder.eq(persistentProperty.getColumnName().toCql(), writeValue.orElse(null))); } return clauses; @@ -554,26 +532,23 @@ public class MappingCassandraConverter extends AbstractCassandraConverter return ((MapIdentifiable) object).getMapId(); } - CassandraPersistentProperty idProperty = entity.getIdProperty(); + Optional optionalIdProperty = entity.getIdProperty(); - if (idProperty != null) { - return accessor.getProperty(idProperty, - idProperty.isCompositePrimaryKey() ? (Class) idProperty.getType() - : (Class) getTargetType(idProperty)); + if (optionalIdProperty.isPresent()) { + // TODO: NullId + CassandraPersistentProperty idProperty = optionalIdProperty.get(); + return accessor.getProperty(idProperty, idProperty.isCompositePrimaryKey() ? (Class) idProperty.getType() + : (Class) getTargetType(idProperty)).orElse(null); } // if the class doesn't have an id property, then it's using MapId final MapId id = id(); - entity.doWithProperties(new PropertyHandler() { - - @Override - public void doWithPersistentProperty(CassandraPersistentProperty property) { - if (property.isPrimaryKeyColumn()) { - id.with(property.getName(), (Serializable) getWriteValue(property, accessor)); - } - } - }); + entity.getPersistentProperties() // + .filter(CassandraPersistentProperty::isPrimaryKeyColumn) // + .forEach(property -> { + id.with(property.getName(), (Serializable) getWriteValue(property, accessor).orElse(null)); + }); return id; } @@ -630,7 +605,7 @@ public class MappingCassandraConverter extends AbstractCassandraConverter return getCustomConversions().getCustomWriteTarget(property.getType()); } - if (property.findAnnotation(CassandraType.class) != null) { + if (property.findAnnotation(CassandraType.class).isPresent()) { return getPropertyTargetType(property); } @@ -665,8 +640,9 @@ public class MappingCassandraConverter extends AbstractCassandraConverter * @return the return value, may be {@literal null}. */ @SuppressWarnings("unchecked") - private Object getWriteValue(CassandraPersistentProperty property, ConvertingPropertyAccessor accessor) { - return getWriteValue(accessor.getProperty(property, getTargetType(property)), property.getTypeInformation()); + private Optional getWriteValue(CassandraPersistentProperty property, ConvertingPropertyAccessor accessor) { + return getWriteValue(accessor.getProperty(property, (Class) getTargetType(property)), + property.getTypeInformation()); } /** @@ -678,19 +654,23 @@ public class MappingCassandraConverter extends AbstractCassandraConverter * @return the return value, may be {@literal null}. */ @SuppressWarnings("unchecked") - private Object getWriteValue(Object value, TypeInformation typeInformation) { + private Optional getWriteValue(Optional optional, TypeInformation typeInformation) { - if (value == null) { - return null; + if (!optional.isPresent()) { + return Optional.empty(); } + I value = optional.get(); + if (getCustomConversions().isSimpleType(value.getClass())) { // Doesn't need conversion - return getPotentiallyConvertedSimpleValue(value, typeInformation.getType()); + return getPotentiallyConvertedSimpleValue(optional, (Class) typeInformation.getType()); } if (getCustomConversions().hasCustomWriteTarget(value.getClass())) { - return getConversionService().convert(value, getCustomConversions().getCustomWriteTarget(value.getClass())); + + return Optional.ofNullable(getConversionService().convert(value, + (Class) getCustomConversions().getCustomWriteTarget(value.getClass()))); } TypeInformation type = (typeInformation != null ? typeInformation : ClassTypeInformation.from(value.getClass())); @@ -702,58 +682,65 @@ public class MappingCassandraConverter extends AbstractCassandraConverter Collection converted = CollectionFactory.createCollection(getCollectionType(type), original.size()); for (Object element : original) { - converted.add(convertToCassandraColumn(element, actualType)); + converted.add(convertToCassandraColumn(Optional.ofNullable(element), actualType).orElse(null)); } - return converted; + return Optional.of((O) converted); } - CassandraPersistentEntity persistentEntity = getMappingContext().getPersistentEntity(actualType.getType()); + Optional> optionalUdt = getMappingContext().getPersistentEntity(actualType.getType()) + .filter(CassandraPersistentEntity::isUserDefinedType); - if (persistentEntity != null && persistentEntity.isUserDefinedType()) { + if (optionalUdt.isPresent()) { - UDTValue udtValue = persistentEntity.getUserType().newValue(); + return optionalUdt.map(persistentEntity -> { - write(value, udtValue, persistentEntity); + UDTValue udtValue = persistentEntity.getUserType().newValue(); + + write(value, udtValue, persistentEntity); + + return (O) udtValue; + }); - return udtValue; } - return value; + return (Optional) optional; } /** * Checks whether we have a custom conversion registered for the given value into an arbitrary simple Cassandra type. * Returns the converted value if so. If not, we perform special enum handling or simply return the value as is. * - * @param value may be {@literal null}. + * @param optionalValue may be {@literal null}. * @param requestedTargetType must not be {@literal null}. * @see CassandraType */ - private Object getPotentiallyConvertedSimpleValue(Object value, Class requestedTargetType) { + @SuppressWarnings("unchecked") + private Optional getPotentiallyConvertedSimpleValue(Optional optionalValue, + Class requestedTargetType) { - if (value == null) { - return null; - } + if (optionalValue.isPresent()) { - if (getCustomConversions().hasCustomWriteTarget(value.getClass(), requestedTargetType)) { - return getConversionService().convert(value, - getCustomConversions().getCustomWriteTarget(value.getClass(), requestedTargetType)); - } - - // Cassandra has no default enum handling - convert it either to string - // or - if requested - to a different type - if (Enum.class.isAssignableFrom(value.getClass())) { - if (requestedTargetType != null && !requestedTargetType.isEnum() - && getConversionService().canConvert(value.getClass(), requestedTargetType)) { - - return getConversionService().convert(value, requestedTargetType); + Object value = optionalValue.get(); + if (getCustomConversions().hasCustomWriteTarget(value.getClass(), requestedTargetType)) { + return Optional.ofNullable((O) getConversionService().convert(value, + getCustomConversions().getCustomWriteTarget(value.getClass(), requestedTargetType))); } - return ((Enum) value).name(); + // Cassandra has no default enum handling - convert it either to string + // or - if requested - to a different type + if (Enum.class.isAssignableFrom(value.getClass())) { + if (requestedTargetType != null && !requestedTargetType.isEnum() + && getConversionService().canConvert(value.getClass(), requestedTargetType)) { + + return Optional.ofNullable(getConversionService().convert(value, requestedTargetType)); + } + + return Optional.of((O) ((Enum) value).name()); + } } - return value; + return (Optional) optionalValue; } /** @@ -812,18 +799,22 @@ public class MappingCassandraConverter extends AbstractCassandraConverter * @return the return value, may be {@literal null}. */ @SuppressWarnings("unchecked") - private Object getReadValue(PropertyValueProvider row, + private Optional getReadValue(PropertyValueProvider row, CassandraPersistentProperty property) { - Object obj = row.getPropertyValue(property); + Optional obj = row.getPropertyValue(property); - if (obj != null) { + if (!obj.isPresent()) { + return Optional.empty(); + } - if (conversions.hasCustomWriteTarget(property.getActualType()) && property.isCollectionLike()) { + if (conversions.hasCustomWriteTarget(property.getActualType()) && property.isCollectionLike()) { - if (Collection.class.isAssignableFrom(property.getType()) && obj instanceof Collection) { + if (obj.filter(it -> it instanceof Collection).isPresent()) { - Collection original = (Collection) obj; + return obj.map(it -> { + + Collection original = (Collection) it; Collection converted = CollectionFactory.createCollection(property.getType(), original.size()); @@ -831,22 +822,25 @@ public class MappingCassandraConverter extends AbstractCassandraConverter converted.add(getConversionService().convert(element, property.getActualType())); } - return converted; - } + return (T) converted; + }); + } } - if (property.isCollectionLike() && obj instanceof Collection) { - return readCollectionOrArray(property.getTypeInformation(), (Collection) obj); + if (property.isCollectionLike() && obj.filter(it -> it instanceof Collection).isPresent()) { + return obj.map(it -> (T) readCollectionOrArray(property.getTypeInformation(), (Collection) it)); } - CassandraPersistentEntity persistentEntity = getMappingContext().getPersistentEntity(property.getActualType()); + Optional> persistentEntity = getMappingContext() + .getPersistentEntity(property.getActualType()).filter(CassandraPersistentEntity::isUserDefinedType); - if (persistentEntity != null && persistentEntity.isUserDefinedType() && obj instanceof UDTValue) { - return readEntityFromUdt(persistentEntity, (UDTValue) obj); + if (persistentEntity.isPresent() && obj.filter(it -> it instanceof UDTValue).isPresent()) { + persistentEntity + .map(cassandraPersistentEntity -> obj.map(it -> readEntityFromUdt(cassandraPersistentEntity, (UDTValue) it))); } - return getPotentiallyConvertedSimpleRead(obj, property.getType()); + return obj.flatMap(it -> Optional.of((T) getPotentiallyConvertedSimpleRead(it, property.getType()))); } /** @@ -864,8 +858,8 @@ public class MappingCassandraConverter extends AbstractCassandraConverter Class collectionType = targetType.getType(); - TypeInformation componentType = targetType.getComponentType(); - Class rawComponentType = componentType == null ? null : componentType.getType(); + Optional> componentType = targetType.getComponentType(); + Class rawComponentType = componentType.map(TypeInformation::getType).orElse((Class) List.class); collectionType = Collection.class.isAssignableFrom(collectionType) ? collectionType : List.class; Collection items = targetType.getType().isArray() ? new ArrayList() @@ -875,13 +869,17 @@ public class MappingCassandraConverter extends AbstractCassandraConverter return getPotentiallyConvertedSimpleRead(items, collectionType); } - CassandraPersistentEntity persistentEntity = getMappingContext().getPersistentEntity(componentType); + Optional> cassandraPersistentEntity = componentType + .flatMap(it -> getMappingContext().getPersistentEntity(it)) + .filter(CassandraPersistentEntity::isUserDefinedType); - if (persistentEntity != null && persistentEntity.isUserDefinedType()) { + if (cassandraPersistentEntity.isPresent()) { - for (Object udtValue : sourceValue) { - items.add(readEntityFromUdt(persistentEntity, (UDTValue) udtValue)); - } + cassandraPersistentEntity.ifPresent(persistentEntity -> { + for (Object udtValue : sourceValue) { + items.add(readEntityFromUdt(persistentEntity, (UDTValue) udtValue)); + } + }); } else { for (Object item : sourceValue) { @@ -920,7 +918,7 @@ public class MappingCassandraConverter extends AbstractCassandraConverter * @see org.springframework.data.mapping.model.PropertyValueProvider#getPropertyValue(org.springframework.data.mapping.PersistentProperty) */ @Override - public Object getPropertyValue(CassandraPersistentProperty property) { + public Optional getPropertyValue(CassandraPersistentProperty property) { return getReadValue(parent, property); } } 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 20da7cf3e..553a313ba 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 @@ -1,5 +1,5 @@ /* - * Copyright 2016 the original author or authors. + * Copyright 2016-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -32,7 +32,6 @@ import org.springframework.cassandra.core.session.DefaultSessionFactory; import org.springframework.cassandra.core.session.SessionFactory; import org.springframework.cassandra.core.support.CQLExceptionTranslator; import org.springframework.dao.DataAccessException; -import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.data.cassandra.convert.CassandraConverter; import org.springframework.data.cassandra.convert.MappingCassandraConverter; import org.springframework.data.cassandra.mapping.CassandraMappingContext; @@ -245,7 +244,7 @@ public class AsyncCassandraTemplate implements AsyncCassandraOperations { public ListenableFuture selectOne(Statement statement, Class entityClass) { return new MappingListenableFutureAdapter<>(select(statement, entityClass), - list -> list.isEmpty() ? null : list.get(0)); + list -> list.stream().findFirst().orElse(null)); } // ------------------------------------------------------------------------- @@ -261,7 +260,8 @@ public class AsyncCassandraTemplate implements AsyncCassandraOperations { Assert.notNull(entityClass, "Entity type must not be null"); - Select select = QueryBuilder.select().countAll().from(getPersistentEntity(entityClass).getTableName().toCql()); + Select select = QueryBuilder.select().countAll() + .from(mappingContext.getRequiredPersistentEntity(entityClass).getTableName().toCql()); return cqlOperations.queryForObject(select, Long.class); } @@ -276,7 +276,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 = getPersistentEntity(entityClass); + CassandraPersistentEntity entity = mappingContext.getRequiredPersistentEntity(entityClass); Select select = QueryBuilder.select().from(entity.getTableName().toCql()); @@ -296,7 +296,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 = getPersistentEntity(entityClass); + CassandraPersistentEntity entity = mappingContext.getRequiredPersistentEntity(entityClass); Select select = QueryBuilder.select().all().from(entity.getTableName().toCql()); @@ -387,7 +387,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 = getPersistentEntity(entityClass); + CassandraPersistentEntity entity = mappingContext.getRequiredPersistentEntity(entityClass); Delete delete = QueryBuilder.delete().from(entity.getTableName().toCql()); @@ -405,27 +405,15 @@ public class AsyncCassandraTemplate implements AsyncCassandraOperations { Assert.notNull(entityClass, "Entity type must not be null"); - Truncate truncate = QueryBuilder.truncate(getPersistentEntity(entityClass).getTableName().toCql()); + Truncate truncate = QueryBuilder + .truncate(mappingContext.getRequiredPersistentEntity(entityClass).getTableName().toCql()); return new MappingListenableFutureAdapter<>(cqlOperations.execute(truncate), aBoolean -> null); } - private CassandraPersistentEntity getPersistentEntity(Class entityClass) { - - Assert.notNull(entityClass, "Entity type must not be null"); - - CassandraPersistentEntity entity = mappingContext.getPersistentEntity(entityClass); - - if (entity == null) { - throw new InvalidDataAccessApiUsageException( - String.format("No Persistent Entity information found for the class [%s]", entityClass.getName())); - } - - return entity; - } - private CqlIdentifier getTableName(Object entity) { - return getPersistentEntity(ClassUtils.getUserClass(entity)).getTableName(); + + return mappingContext.getRequiredPersistentEntity(ClassUtils.getUserClass(entity)).getTableName(); } private static class MappingListenableFutureAdapter diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/CassandraAdminOperations.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/CassandraAdminOperations.java index 3882fcb84..cbc70300e 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/CassandraAdminOperations.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/CassandraAdminOperations.java @@ -16,12 +16,13 @@ package org.springframework.data.cassandra.core; import java.util.Map; +import java.util.Optional; + +import org.springframework.cassandra.core.cql.CqlIdentifier; import com.datastax.driver.core.KeyspaceMetadata; import com.datastax.driver.core.TableMetadata; -import org.springframework.cassandra.core.cql.CqlIdentifier; - /** * Operations for managing a Cassandra keyspace. * @@ -61,7 +62,7 @@ public interface CassandraAdminOperations extends CassandraOperations { * @param tableName must not be {@literal null}. * @return the {@link TableMetadata} or {@literal null}. */ - TableMetadata getTableMetadata(String keyspace, CqlIdentifier tableName); + Optional getTableMetadata(String keyspace, CqlIdentifier tableName); /** * Returns {@link KeyspaceMetadata} for the current keyspace. diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/CassandraAdminTemplate.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/CassandraAdminTemplate.java index 0aac1c459..ed04ae9ab 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/CassandraAdminTemplate.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/CassandraAdminTemplate.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2016 the original author or authors. + * Copyright 2013-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,7 +16,10 @@ package org.springframework.data.cassandra.core; import java.util.Map; +import java.util.Optional; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.cassandra.core.SessionCallback; import org.springframework.cassandra.core.cql.CqlIdentifier; import org.springframework.cassandra.core.cql.generator.CreateTableCqlGenerator; @@ -72,7 +75,7 @@ public class CassandraAdminTemplate extends CassandraTemplate implements Cassand public void createTable(boolean ifNotExists, CqlIdentifier tableName, Class entityClass, Map optionsByName) { - CassandraPersistentEntity entity = getPersistentEntity(entityClass); + CassandraPersistentEntity entity = getConverter().getMappingContext().getRequiredPersistentEntity(entityClass); CreateTableSpecification createTableSpecification = getConverter().getMappingContext() .getCreateTableSpecificationFor(entity).ifNotExists(ifNotExists); @@ -110,13 +113,13 @@ public class CassandraAdminTemplate extends CassandraTemplate implements Cassand * @see org.springframework.data.cassandra.core.CassandraAdminOperations#getTableMetadata(java.lang.String, org.springframework.cassandra.core.cql.CqlIdentifier) */ @Override - public TableMetadata getTableMetadata(String keyspace, CqlIdentifier tableName) { + public Optional getTableMetadata(String keyspace, CqlIdentifier tableName) { Assert.hasText(keyspace, "Keyspace name must not be empty"); Assert.notNull(tableName, "Table name must not be null"); - return getCqlOperations().execute((SessionCallback) session -> session.getCluster().getMetadata() - .getKeyspace(keyspace).getTable(tableName.toCql())); + return Optional.ofNullable(getCqlOperations().execute((SessionCallback) session -> session + .getCluster().getMetadata().getKeyspace(keyspace).getTable(tableName.toCql()))); } /* @@ -126,19 +129,16 @@ public class CassandraAdminTemplate extends CassandraTemplate implements Cassand @Override public KeyspaceMetadata getKeyspaceMetadata() { - return getCqlOperations().execute(new SessionCallback() { + return getCqlOperations().execute((SessionCallback) session -> { - @Override - public KeyspaceMetadata doInSession(Session session) throws DataAccessException { + KeyspaceMetadata keyspaceMetadata = session.getCluster().getMetadata().getKeyspace(session.getLoggedKeyspace()); - KeyspaceMetadata keyspaceMetadata = session.getCluster().getMetadata() - .getKeyspace(session.getLoggedKeyspace()); - Assert.state(keyspaceMetadata != null, - String.format("Metadata for keyspace [%s] not available", session.getLoggedKeyspace())); - return keyspaceMetadata; - } + Assert.state(keyspaceMetadata != null, String.format("Metadata for keyspace [%s] not available", + session.getLoggedKeyspace())); + + return keyspaceMetadata; }); } } 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 05ea2c0c8..844e51b2d 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 @@ -19,8 +19,6 @@ import java.util.Iterator; import java.util.List; import java.util.stream.Stream; -import com.datastax.driver.core.Statement; - import org.springframework.cassandra.core.CqlOperations; import org.springframework.cassandra.core.QueryOptions; import org.springframework.cassandra.core.WriteOptions; @@ -28,6 +26,8 @@ import org.springframework.cassandra.core.cql.CqlIdentifier; import org.springframework.dao.DataAccessException; import org.springframework.data.cassandra.convert.CassandraConverter; +import com.datastax.driver.core.Statement; + /** * Interface specifying a basic set of Cassandra operations. Implemented by {@link CassandraTemplate}. Not often used * directly, but a useful option to enhance testability, as it can easily be mocked or stubbed. diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/CassandraPersistentEntitySchemaCreator.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/CassandraPersistentEntitySchemaCreator.java index 9b47610d9..6766c3b68 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/CassandraPersistentEntitySchemaCreator.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/CassandraPersistentEntitySchemaCreator.java @@ -32,8 +32,7 @@ import org.springframework.cassandra.core.keyspace.CreateTableSpecification; import org.springframework.cassandra.core.keyspace.CreateUserTypeSpecification; import org.springframework.data.cassandra.mapping.CassandraMappingContext; import org.springframework.data.cassandra.mapping.CassandraPersistentEntity; -import org.springframework.data.cassandra.mapping.CassandraPersistentProperty; -import org.springframework.data.mapping.PropertyHandler; +import org.springframework.data.util.Optionals; import org.springframework.util.Assert; /** @@ -123,8 +122,7 @@ public class CassandraPersistentEntitySchemaCreator { List specifications = new ArrayList<>(); Set created = new HashSet<>(); - - for (CassandraPersistentEntity entity : entities) { + entities.forEach(entity -> { Set seen = new LinkedHashSet<>(); @@ -138,25 +136,22 @@ public class CassandraPersistentEntitySchemaCreator { .filter(created::add).map(identifier -> mappingContext .getCreateUserTypeSpecificationFor(byTableName.get(identifier)).ifNotExists(ifNotExists)) .collect(Collectors.toList())); - } + + }); return specifications; } private void visitUserTypes(CassandraPersistentEntity entity, final Set seen) { - entity.doWithProperties(new PropertyHandler() { - - @Override - public void doWithPersistentProperty(CassandraPersistentProperty persistentProperty) { - CassandraPersistentEntity persistentEntity = mappingContext.getPersistentEntity(persistentProperty); - - if (persistentEntity != null && persistentEntity.isUserDefinedType()) { + entity.getPersistentProperties() // + .map(mappingContext::getPersistentEntity) // + .flatMap(Optionals::toStream) // + .filter(CassandraPersistentEntity::isUserDefinedType).forEach(persistentEntity -> { if (seen.add(persistentEntity.getTableName())) { visitUserTypes(persistentEntity, seen); } - } - } - }); + }); + } } 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 9f981c324..11ab09f02 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 @@ -16,6 +16,8 @@ package org.springframework.data.cassandra.core; import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; import java.util.stream.Stream; import java.util.stream.StreamSupport; @@ -30,11 +32,11 @@ import org.springframework.cassandra.core.session.DefaultSessionFactory; import org.springframework.cassandra.core.session.SessionFactory; import org.springframework.cassandra.core.util.CollectionUtils; import org.springframework.dao.DataAccessException; -import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.data.cassandra.convert.CassandraConverter; import org.springframework.data.cassandra.convert.MappingCassandraConverter; import org.springframework.data.cassandra.mapping.CassandraMappingContext; import org.springframework.data.cassandra.mapping.CassandraPersistentEntity; +import org.springframework.data.cassandra.mapping.CassandraPersistentProperty; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; @@ -223,7 +225,7 @@ public class CassandraTemplate implements CassandraOperations { List result = select(statement, entityClass); - return (result.isEmpty() ? null : result.get(0)); + return result.stream().findFirst().orElse(null); } // ------------------------------------------------------------------------- @@ -239,7 +241,8 @@ public class CassandraTemplate implements CassandraOperations { Assert.notNull(entityClass, "Entity type must not be null"); - Select select = QueryBuilder.select().countAll().from(getPersistentEntity(entityClass).getTableName().toCql()); + Select select = QueryBuilder.select().countAll() + .from(mappingContext.getRequiredPersistentEntity(entityClass).getTableName().toCql()); return cqlOperations.queryForObject(select, Long.class); } @@ -254,7 +257,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 = getPersistentEntity(entityClass); + CassandraPersistentEntity entity = mappingContext.getRequiredPersistentEntity(entityClass); Select select = QueryBuilder.select().from(entity.getTableName().toCql()); @@ -273,7 +276,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 = getPersistentEntity(entityClass); + CassandraPersistentEntity entity = mappingContext.getRequiredPersistentEntity(entityClass); Select select = QueryBuilder.select().all().from(entity.getTableName().toCql()); @@ -288,12 +291,13 @@ public class CassandraTemplate implements CassandraOperations { Assert.notNull(ids, "Ids must not be null"); Assert.notNull(entityClass, "EntityClass must not be null"); - CassandraPersistentEntity entity = getPersistentEntity(entityClass); + CassandraPersistentEntity entity = mappingContext.getRequiredPersistentEntity(entityClass); - if (entity.getIdProperty() == null || entity.getIdProperty().isCompositePrimaryKey()) { - String typeName = (entity.getIdProperty() == null ? "Unknown" - : entity.getIdProperty().getCompositePrimaryKeyEntity().getType().getName()); + CassandraPersistentProperty idProperty = entity.getIdProperty().orElseThrow(() -> new IllegalArgumentException( + String.format("Entity class [%s] has no primary key", entityClass.getName()))); + if (idProperty.isCompositePrimaryKey()) { + String typeName = idProperty.getCompositePrimaryKeyEntity().getType().getName(); throw new IllegalArgumentException( String.format("Entity class [%s] uses a composite primary key class [%s] which this method can't support", entityClass.getName(), typeName)); @@ -301,7 +305,7 @@ public class CassandraTemplate implements CassandraOperations { Select select = QueryBuilder.select().all().from(entity.getTableName().toCql()); - select.where(QueryBuilder.in(entity.getIdProperty().getColumnName().toCql(), CollectionUtils.toArray(ids))); + select.where(QueryBuilder.in(idProperty.getColumnName().toCql(), CollectionUtils.toArray(ids))); return select(select, entityClass); } @@ -325,7 +329,7 @@ public class CassandraTemplate implements CassandraOperations { Assert.notNull(entity, "Entity must not be null"); Insert insert = QueryUtils.createInsertQuery(getTableName(entity.getClass()).toCql(), - entity, options, converter); + entity, options, converter); return cqlOperations.execute(new StatementCallback<>(insert, entity)); } @@ -349,7 +353,7 @@ public class CassandraTemplate implements CassandraOperations { Assert.notNull(entity, "Entity must not be null"); Update update = QueryUtils.createUpdateQuery(getTableName(entity.getClass()).toCql(), - entity, options, converter); + entity, options, converter); return cqlOperations.execute(new StatementCallback<>(update, entity)); } @@ -373,7 +377,7 @@ public class CassandraTemplate implements CassandraOperations { Assert.notNull(entity, "Entity must not be null"); Delete delete = QueryUtils.createDeleteQuery(getTableName(entity.getClass()).toCql(), - entity, options, converter); + entity, options, converter); return cqlOperations.execute(new StatementCallback<>(delete, entity)); } @@ -388,7 +392,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 = getPersistentEntity(entityClass); + CassandraPersistentEntity entity = mappingContext.getRequiredPersistentEntity(entityClass); Delete delete = QueryBuilder.delete().from(entity.getTableName().toCql()); @@ -406,7 +410,8 @@ public class CassandraTemplate implements CassandraOperations { Assert.notNull(entityClass, "Entity type must not be null"); - Truncate truncate = QueryBuilder.truncate(getPersistentEntity(entityClass).getTableName().toCql()); + Truncate truncate = QueryBuilder + .truncate(mappingContext.getRequiredPersistentEntity(entityClass).getTableName().toCql()); cqlOperations.execute(truncate); } @@ -433,27 +438,13 @@ public class CassandraTemplate implements CassandraOperations { return cqlOperations; } - protected CassandraPersistentEntity getPersistentEntity(Class entityClass) { - - Assert.notNull(entityClass, "Entity type must not be null"); - - CassandraPersistentEntity entity = mappingContext.getPersistentEntity(entityClass); - - if (entity == null) { - throw new InvalidDataAccessApiUsageException( - String.format("No Persistent Entity information found for the class [%s]", entityClass.getName())); - } - - return entity; - } - /* * (non-Javadoc) * @see org.springframework.data.cassandra.core.CassandraOperationsNG#getTableName(java.lang.Class) */ @Override public CqlIdentifier getTableName(Class entityClass) { - return getPersistentEntity(ClassUtils.getUserClass(entityClass)).getTableName(); + return mappingContext.getRequiredPersistentEntity(ClassUtils.getUserClass(entityClass)).getTableName(); } /* 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 755451fcc..ffa98ee04 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 @@ -1,5 +1,5 @@ /* - * Copyright 2016 the original author or authors. + * Copyright 2016-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,6 +18,20 @@ package org.springframework.data.cassandra.core; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; +import org.reactivestreams.Publisher; +import org.springframework.cassandra.core.*; +import org.springframework.cassandra.core.cql.CqlIdentifier; +import org.springframework.dao.DataAccessException; +import org.springframework.data.cassandra.convert.CassandraConverter; +import org.springframework.data.cassandra.convert.MappingCassandraConverter; +import org.springframework.data.cassandra.mapping.CassandraMappingContext; +import org.springframework.data.cassandra.mapping.CassandraPersistentEntity; +import org.springframework.util.Assert; +import org.springframework.util.ClassUtils; + +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + import org.reactivestreams.Publisher; import org.springframework.cassandra.core.CqlProvider; import org.springframework.cassandra.core.QueryOptions; @@ -214,7 +228,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 = getPersistentEntity(entityClass); + CassandraPersistentEntity entity = mappingContext.getRequiredPersistentEntity(entityClass); Select select = QueryBuilder.select().all().from(entity.getTableName().toCql()); @@ -233,7 +247,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 = getPersistentEntity(entityClass); + CassandraPersistentEntity entity = mappingContext.getRequiredPersistentEntity(entityClass); Select select = QueryBuilder.select().from(entity.getTableName().toCql()); @@ -251,7 +265,7 @@ public class ReactiveCassandraTemplate implements ReactiveCassandraOperations { Assert.notNull(entityClass, "Entity type must not be null"); - Select select = QueryBuilder.select().countAll().from(getPersistentEntity(entityClass).getTableName().toCql()); + Select select = QueryBuilder.select().countAll().from(mappingContext.getRequiredPersistentEntity(entityClass).getTableName().toCql()); return cqlOperations.queryForObject(select, Long.class); } @@ -382,7 +396,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 = getPersistentEntity(entityClass); + CassandraPersistentEntity entity = mappingContext.getRequiredPersistentEntity(entityClass); Delete delete = QueryBuilder.delete().from(entity.getTableName().toCql()); @@ -458,7 +472,7 @@ public class ReactiveCassandraTemplate implements ReactiveCassandraOperations { Assert.notNull(entityClass, "Entity type must not be null"); - Truncate truncate = QueryBuilder.truncate(getPersistentEntity(entityClass).getTableName().toCql()); + Truncate truncate = QueryBuilder.truncate(mappingContext.getRequiredPersistentEntity(entityClass).getTableName().toCql()); return cqlOperations.execute(truncate).then(); } @@ -481,21 +495,7 @@ public class ReactiveCassandraTemplate implements ReactiveCassandraOperations { return cqlOperations; } - private CassandraPersistentEntity getPersistentEntity(Class entityClass) { - - Assert.notNull(entityClass, "Entity type must not be null"); - - CassandraPersistentEntity entity = mappingContext.getPersistentEntity(entityClass); - - if (entity == null) { - throw new InvalidDataAccessApiUsageException( - String.format("No Persistent Entity information found for the class [%s]", entityClass.getName())); - } - - return entity; - } - private CqlIdentifier getTableName(Object entity) { - return getPersistentEntity(ClassUtils.getUserClass(entity)).getTableName(); + return mappingContext.getRequiredPersistentEntity(ClassUtils.getUserClass(entity)).getTableName(); } } diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/mapping/BasicCassandraMappingContext.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/mapping/BasicCassandraMappingContext.java index 191f57881..48d62048f 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/mapping/BasicCassandraMappingContext.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/mapping/BasicCassandraMappingContext.java @@ -19,16 +19,14 @@ import static org.springframework.cassandra.core.cql.CqlIdentifier.*; import static org.springframework.cassandra.core.keyspace.CreateTableSpecification.*; import static org.springframework.data.cassandra.mapping.CassandraSimpleTypeHolder.*; -import java.beans.PropertyDescriptor; -import java.lang.reflect.Field; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.Set; -import java.util.concurrent.atomic.AtomicBoolean; import org.springframework.beans.BeansException; import org.springframework.cassandra.core.cql.CqlIdentifier; @@ -38,11 +36,14 @@ import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.core.annotation.AnnotatedElementUtils; import org.springframework.data.cassandra.convert.CustomConversions; +import org.springframework.data.mapping.PersistentEntity; import org.springframework.data.mapping.PropertyHandler; import org.springframework.data.mapping.context.AbstractMappingContext; import org.springframework.data.mapping.context.MappingContext; import org.springframework.data.mapping.model.MappingException; +import org.springframework.data.mapping.model.Property; import org.springframework.data.mapping.model.SimpleTypeHolder; +import org.springframework.data.util.Optionals; import org.springframework.data.util.TypeInformation; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; @@ -75,12 +76,12 @@ public class BasicCassandraMappingContext protected Mapping mapping = new Mapping(); // useful caches - protected Map, CassandraPersistentEntity> entitiesByType = new HashMap, CassandraPersistentEntity>(); - protected Map>> entitySetsByTableName = new HashMap>>(); + protected Map, CassandraPersistentEntity> entitiesByType = new HashMap<>(); + protected Map>> entitySetsByTableName = new HashMap<>(); - protected Set> primaryKeyEntities = new HashSet>(); - protected Set> userDefinedTypes = new HashSet>(); - protected Set> tableEntities = new HashSet>(); + protected Set> primaryKeyEntities = new HashSet<>(); + protected Set> userDefinedTypes = new HashSet<>(); + protected Set> tableEntities = new HashSet<>(); private CustomConversions customConversions; @@ -107,33 +108,27 @@ public class BasicCassandraMappingContext @SuppressWarnings("all") protected void processMappingOverrides() { - if (mapping != null) { + mapping.getEntityMappings().stream()// + .filter(entityMapping -> entityMapping != null).forEach(entityMapping -> { + String entityClassName = entityMapping.getEntityClassName(); - mapping.getEntityMappings().stream() // - .filter(entityMapping -> entityMapping != null) // - .forEach(entityMapping -> { + try { + Class entityClass = ClassUtils.forName(entityClassName, beanClassLoader); - String entityClassName = entityMapping.getEntityClassName(); + CassandraPersistentEntity entity = getRequiredPersistentEntity(entityClass); - try { - Class entityClass = ClassUtils.forName(entityClassName, beanClassLoader); + String entityTableName = entityMapping.getTableName(); - CassandraPersistentEntity entity = getPersistentEntity(entityClass); - - Assert.state(entity != null, String.format("Unknown persistent entity class name [%s]", entityClassName)); - - String entityTableName = entityMapping.getTableName(); - - if (StringUtils.hasText(entityTableName)) { - entity.setTableName(cqlId(entityTableName, Boolean.valueOf(entityMapping.getForceQuote()))); - } - - processMappingOverrides(entity, entityMapping); - } catch (ClassNotFoundException e) { - throw new IllegalStateException(String.format("Unknown persistent entity name [%s]", entityClassName), e); + if (StringUtils.hasText(entityTableName)) { + entity.setTableName(cqlId(entityTableName, Boolean.valueOf(entityMapping.getForceQuote()))); } - }); - } + + processMappingOverrides(entity, entityMapping); + + } catch (ClassNotFoundException e) { + throw new IllegalStateException(String.format("Unknown persistent entity name [%s]", entityClassName), e); + } + }); } protected void processMappingOverrides(CassandraPersistentEntity entity, EntityMapping entityMapping) { @@ -143,10 +138,7 @@ public class BasicCassandraMappingContext protected void processMappingOverride(CassandraPersistentEntity entity, PropertyMapping mapping) { - CassandraPersistentProperty property = entity.getPersistentProperty(mapping.getPropertyName()); - - Assert.notNull(property, String.format("Entity class [%s] has no persistent property named [%s]", - entity.getType().getName(), mapping.getPropertyName())); + CassandraPersistentProperty property = entity.getRequiredPersistentProperty(mapping.getPropertyName()); boolean forceQuote = Boolean.valueOf(mapping.getForceQuote()); @@ -287,12 +279,8 @@ public class BasicCassandraMappingContext // now do some caching of the entity - Set> entities = entitySetsByTableName.get(entity.getTableName()); - - if (entities == null) { - entities = new HashSet>(); - entitySetsByTableName.put(entity.getTableName(), entities); - } + Set> entities = entitySetsByTableName.computeIfAbsent(entity.getTableName(), + cqlIdentifier -> new HashSet<>()); entities.add(entity); @@ -301,9 +289,7 @@ public class BasicCassandraMappingContext primaryKeyEntities.add(entity); } - if (entity.findAnnotation(Table.class) != null) { - tableEntities.add(entity); - } + entity.findAnnotation(Table.class).ifPresent(table -> tableEntities.add(entity)); } entitiesByType.put(entity.getType(), entity); @@ -315,14 +301,14 @@ public class BasicCassandraMappingContext * @see org.springframework.data.mapping.context.AbstractMappingContext#createPersistentProperty(java.lang.reflect.Field, java.beans.PropertyDescriptor, org.springframework.data.mapping.model.MutablePersistentEntity, org.springframework.data.mapping.model.SimpleTypeHolder) */ @Override - public CassandraPersistentProperty createPersistentProperty(Field field, PropertyDescriptor descriptor, - CassandraPersistentEntity owner, SimpleTypeHolder simpleTypeHolder) { - return createPersistentProperty(field, descriptor, owner, (CassandraSimpleTypeHolder) simpleTypeHolder); + protected CassandraPersistentProperty createPersistentProperty(Property property, CassandraPersistentEntity owner, + SimpleTypeHolder simpleTypeHolder) { + return createPersistentProperty(property, owner, (CassandraSimpleTypeHolder) simpleTypeHolder); } - public CassandraPersistentProperty createPersistentProperty(Field field, PropertyDescriptor descriptor, - CassandraPersistentEntity owner, CassandraSimpleTypeHolder simpleTypeHolder) { - return new BasicCassandraPersistentProperty(field, descriptor, owner, simpleTypeHolder, userTypeResolver); + public CassandraPersistentProperty createPersistentProperty(Property property, CassandraPersistentEntity owner, + CassandraSimpleTypeHolder simpleTypeHolder) { + return new BasicCassandraPersistentProperty(property, owner, simpleTypeHolder, userTypeResolver); } /* (non-Javadoc) @@ -346,28 +332,15 @@ public class BasicCassandraMappingContext private boolean hasReferencedUserType(final CqlIdentifier identifier) { - final AtomicBoolean foundReference = new AtomicBoolean(); - - getPersistentEntities() - .forEach(entity -> entity.doWithProperties(new PropertyHandler() { - - @Override - public void doWithPersistentProperty(CassandraPersistentProperty persistentProperty) { - - CassandraType cassandraType = persistentProperty.findAnnotation(CassandraType.class); - - if (cassandraType == null) { - return; - } - - if (StringUtils.hasText(cassandraType.userTypeName()) - && CqlIdentifier.cqlId(cassandraType.userTypeName()).equals(identifier)) { - foundReference.set(true); - } - } - })); - - return foundReference.get(); + return getPersistentEntities().stream() // + .flatMap(PersistentEntity::getPersistentProperties) // + .map(it -> it.findAnnotation(CassandraType.class)) // + .filter(Optional::isPresent) // + .flatMap(Optionals::toStream) // + .anyMatch(it -> { + return StringUtils.hasText(it.userTypeName()) // + && CqlIdentifier.cqlId(it.userTypeName()).equals(identifier); + }); // } private boolean hasMappedUserType(CqlIdentifier identifier) { @@ -391,35 +364,32 @@ public class BasicCassandraMappingContext final CreateTableSpecification specification = createTable().name(entity.getTableName()); - entity.doWithProperties(new PropertyHandler() { + entity.getPersistentProperties().filter(CassandraPersistentProperty::isCompositePrimaryKey).forEach(property -> { - @Override - public void doWithPersistentProperty(CassandraPersistentProperty property) { - if (property.isCompositePrimaryKey()) { - CassandraPersistentEntity primaryKeyEntity = getPersistentEntity(property.getRawType()); + CassandraPersistentEntity primaryKeyEntity = getRequiredPersistentEntity(property.getRawType()); - primaryKeyEntity.doWithProperties(new PropertyHandler() { + primaryKeyEntity.getPersistentProperties().forEach(primaryKeyProperty -> { - @Override - public void doWithPersistentProperty(CassandraPersistentProperty primaryKeyProperty) { - if (primaryKeyProperty.isPartitionKeyColumn()) { - specification.partitionKeyColumn(primaryKeyProperty.getColumnName(), getDataType(primaryKeyProperty)); - } else { // it's a cluster column - specification.clusteredKeyColumn(primaryKeyProperty.getColumnName(), getDataType(primaryKeyProperty), - primaryKeyProperty.getPrimaryKeyOrdering()); - } - } - }); - } else { - if (property.isIdProperty() || property.isPartitionKeyColumn()) { - specification.partitionKeyColumn(property.getColumnName(), getDataType(property)); - } else if (property.isClusterKeyColumn()) { - specification.clusteredKeyColumn(property.getColumnName(), getDataType(property), - property.getPrimaryKeyOrdering()); - } else { - specification.column(property.getColumnName(), getDataType(property)); - } + if (primaryKeyProperty.isPartitionKeyColumn()) { + specification.partitionKeyColumn(primaryKeyProperty.getColumnName(), getDataType(primaryKeyProperty)); + } else { // it's a cluster column + specification.clusteredKeyColumn(primaryKeyProperty.getColumnName(), getDataType(primaryKeyProperty), + primaryKeyProperty.getPrimaryKeyOrdering()); } + + }); + + }); + + entity.getPersistentProperties().filter((property) -> !property.isCompositePrimaryKey()).forEach(property -> { + if (property.isIdProperty() || property.isPartitionKeyColumn()) { + specification.partitionKeyColumn(property.getColumnName(), getDataType(property)); + } else if (property.isClusterKeyColumn()) { + specification.clusteredKeyColumn(property.getColumnName(), getDataType(property), + property.getPrimaryKeyOrdering()); + } else { + specification.column(property.getColumnName(), getDataType(property)); + } }); @@ -472,9 +442,10 @@ public class BasicCassandraMappingContext * @see org.springframework.data.mapping.context.AbstractMappingContext#addPersistentEntity(org.springframework.data.util.TypeInformation) */ @Override - protected CassandraPersistentEntity addPersistentEntity(TypeInformation typeInformation) { + protected Optional> addPersistentEntity(TypeInformation typeInformation) { // Prevent conversion types created as CassandraPersistentEntity - return (shouldCreatePersistentEntityFor(typeInformation) ? super.addPersistentEntity(typeInformation) : null); + return (shouldCreatePersistentEntityFor(typeInformation) ? super.addPersistentEntity(typeInformation) + : Optional.empty()); } /* (non-Javadoc) @@ -492,19 +463,14 @@ public class BasicCassandraMappingContext return property.getDataType(); } - if (property.findAnnotation(CassandraType.class) != null) { + if (property.findAnnotation(CassandraType.class).isPresent()) { return property.getDataType(); } - CassandraPersistentEntity persistentEntity = getPersistentEntity(property.getActualType()); + Optional> persistentEntity = getPersistentEntity(property.getActualType()); - if (persistentEntity != null && persistentEntity.isUserDefinedType()) { - - DataType elementType = getUserDataType(property, dataTypeProvider, persistentEntity); - - if (elementType != null) { - return elementType; - } + if (persistentEntity.filter(CassandraPersistentEntity::isUserDefinedType).isPresent()) { + return persistentEntity.get().getUserType(); } if (customConversions.hasCustomWriteTarget(property.getType())) { diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/mapping/BasicCassandraPersistentEntity.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/mapping/BasicCassandraPersistentEntity.java index 7220ceb83..ec6d00b2b 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/mapping/BasicCassandraPersistentEntity.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/mapping/BasicCassandraPersistentEntity.java @@ -18,7 +18,9 @@ package org.springframework.data.cassandra.mapping; import static org.springframework.cassandra.core.cql.CqlIdentifier.*; import java.util.ArrayList; +import java.util.Comparator; import java.util.List; +import java.util.Optional; import org.springframework.beans.BeansException; import org.springframework.cassandra.core.cql.CqlIdentifier; @@ -30,7 +32,6 @@ import org.springframework.context.expression.BeanFactoryResolver; import org.springframework.data.cassandra.util.SpelUtils; import org.springframework.data.mapping.Association; import org.springframework.data.mapping.AssociationHandler; -import org.springframework.data.mapping.PropertyHandler; import org.springframework.data.mapping.model.BasicPersistentEntity; import org.springframework.data.mapping.model.MappingException; import org.springframework.data.util.TypeInformation; @@ -53,15 +54,18 @@ public class BasicCassandraPersistentEntity extends BasicPersistentEntity> PROPERTY_COMPARATOR = Optional + .of(CassandraPersistentPropertyComparator.INSTANCE); + protected ApplicationContext context; - protected Boolean forceQuote; + protected Optional forceQuote = Optional.empty(); protected CassandraMappingContext mappingContext; protected CassandraPersistentEntityMetadataVerifier verifier = DEFAULT_VERIFIER; - protected CqlIdentifier tableName; + protected Optional tableName = Optional.empty(); protected StandardEvaluationContext spelContext; @@ -93,7 +97,8 @@ public class BasicCassandraPersistentEntity extends BasicPersistentEntity typeInformation, CassandraMappingContext mappingContext, CassandraPersistentEntityMetadataVerifier verifier) { - super(typeInformation, CassandraPersistentPropertyComparator.INSTANCE); + // FIXME: Constructor with comparator, no optionality here + super(typeInformation, PROPERTY_COMPARATOR); this.mappingContext = mappingContext; @@ -102,10 +107,11 @@ public class BasicCassandraPersistentEntity extends BasicPersistentEntity tableAnnotation = findAnnotation(Table.class); - return (tableAnnotation != null ? determineName(tableAnnotation.value(), tableAnnotation.forceQuote()) - : determineDefaultName()); + return tableAnnotation // + .map(annotation -> determineName(annotation.value(), annotation.forceQuote())) // + .orElseGet(this::determineDefaultName); } /* (non-Javadoc) @@ -129,7 +135,7 @@ public class BasicCassandraPersistentEntity extends BasicPersistentEntity extends BasicPersistentEntity compositePrimaryKeyEntity, final List properties) { - compositePrimaryKeyEntity.doWithProperties(new PropertyHandler() { + compositePrimaryKeyEntity.getPersistentProperties().forEach(property -> { - @Override - public void doWithPersistentProperty(CassandraPersistentProperty property) { - if (property.isCompositePrimaryKey()) { - addCompositePrimaryKeyProperties(property.getCompositePrimaryKeyEntity(), properties); - } else { - properties.add(property); - } + if (property.isCompositePrimaryKey()) { + addCompositePrimaryKeyProperties(property.getCompositePrimaryKeyEntity(), properties); + } else { + properties.add(property); } + }); } @@ -174,6 +178,10 @@ public class BasicCassandraPersistentEntity extends BasicPersistentEntity extends BasicPersistentEntity v != forceQuote).isPresent(); + + this.forceQuote = Optional.of(forceQuote); + + if (changed) { + setTableName(cqlId(getTableName().getUnquoted(), forceQuote)); } } @@ -225,7 +237,7 @@ public class BasicCassandraPersistentEntity extends BasicPersistentEntity extends BasicPersistentEntity entity) throws MappingException { - if (entity.getType().isInterface() || entity.findAnnotation(Table.class) == null) { + if (entity.getType().isInterface() || !entity.findAnnotation(Table.class).isPresent()) { return; } - List exceptions = new ArrayList(); + List exceptions = new ArrayList<>(); - final List idProperties = new ArrayList(); - final List partitionKeyColumns = new ArrayList(); - final List primaryKeyColumns = new ArrayList(); + final List idProperties = new ArrayList<>(); + final List partitionKeyColumns = new ArrayList<>(); + final List primaryKeyColumns = new ArrayList<>(); // Ensure entity is not both a @Table(@Persistent) and a @PrimaryKeyClass if (entity.isCompositePrimaryKey()) { @@ -63,24 +61,20 @@ public class BasicCassandraPersistentEntityMetadataVerifier implements Cassandra } // Parse entity properties - entity.doWithProperties(new PropertyHandler() { - - @Override - public void doWithPersistentProperty(CassandraPersistentProperty property) { - if (property.isIdProperty()) { - idProperties.add(property); - } else if (property.isClusterKeyColumn()) { - primaryKeyColumns.add(property); - } else if (property.isPartitionKeyColumn()) { - partitionKeyColumns.add(property); - primaryKeyColumns.add(property); - } + entity.getPersistentProperties().forEach(property -> { + if (property.isIdProperty()) { + idProperties.add(property); + } else if (property.isClusterKeyColumn()) { + primaryKeyColumns.add(property); + } else if (property.isPartitionKeyColumn()) { + partitionKeyColumns.add(property); + primaryKeyColumns.add(property); } }); // Perform rules verification on Table/Persistent // TODO Verify annotation values with CqlIndentifier - + /* * Perform rules verification on Table/Persistent */ @@ -89,9 +83,9 @@ public class BasicCassandraPersistentEntityMetadataVerifier implements Cassandra // Can only have one PK if (idProperties.size() != 1) { - exceptions.add(new MappingException(String.format( - "@%s types must have only one primary attribute, if any; Found %s", - Table.class.getSimpleName(), idProperties.size()))); + exceptions + .add(new MappingException(String.format("@%s types must have only one primary attribute, if any; Found %s", + Table.class.getSimpleName(), idProperties.size()))); fail(entity, exceptions); } @@ -108,9 +102,9 @@ public class BasicCassandraPersistentEntityMetadataVerifier implements Cassandra // We have no PKs & only PK Column(s); ensure at least one is of type PARTITIONED if (!primaryKeyColumns.isEmpty() && partitionKeyColumns.isEmpty()) { - exceptions.add(new MappingException(String.format( - "At least one of the @%s annotations must have a type of PARTITIONED", - PrimaryKeyColumn.class.getSimpleName()))); + exceptions + .add(new MappingException(String.format("At least one of the @%s annotations must have a type of PARTITIONED", + PrimaryKeyColumn.class.getSimpleName()))); } // Determine whether or not to throw Exception based on errors found diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/mapping/BasicCassandraPersistentProperty.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/mapping/BasicCassandraPersistentProperty.java index a3b0c97af..589799436 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/mapping/BasicCassandraPersistentProperty.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/mapping/BasicCassandraPersistentProperty.java @@ -17,12 +17,11 @@ package org.springframework.data.cassandra.mapping; import static org.springframework.cassandra.core.cql.CqlIdentifier.*; -import java.beans.PropertyDescriptor; -import java.lang.reflect.Field; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.Set; import org.springframework.cassandra.core.Ordering; @@ -36,9 +35,9 @@ import org.springframework.core.annotation.AnnotatedElementUtils; import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.data.cassandra.util.SpelUtils; import org.springframework.data.mapping.Association; -import org.springframework.data.mapping.PropertyHandler; import org.springframework.data.mapping.model.AnnotationBasedPersistentProperty; import org.springframework.data.mapping.model.MappingException; +import org.springframework.data.mapping.model.Property; import org.springframework.data.util.ClassTypeInformation; import org.springframework.data.util.TypeInformation; import org.springframework.expression.spel.support.StandardEvaluationContext; @@ -86,31 +85,28 @@ public class BasicCassandraPersistentProperty extends AnnotationBasedPersistentP /** * Create a new {@link BasicCassandraPersistentProperty}. * - * @param field the actual {@link Field} in the domain entity corresponding to this persistent entity. - * @param propertyDescriptor a {@link PropertyDescriptor} for the corresponding property in the domain entity. + * @param property the actual {@link Property} in the domain entity corresponding to this persistent entity. * @param owner the containing object or {@link CassandraPersistentEntity} of this persistent property. * @param simpleTypeHolder mapping of Java [simple|wrapper] types to Cassandra data types. */ - public BasicCassandraPersistentProperty(Field field, PropertyDescriptor propertyDescriptor, - CassandraPersistentEntity owner, CassandraSimpleTypeHolder simpleTypeHolder) { + public BasicCassandraPersistentProperty(Property property, CassandraPersistentEntity owner, + CassandraSimpleTypeHolder simpleTypeHolder) { - this(field, propertyDescriptor, owner, simpleTypeHolder, null); + this(property, owner, simpleTypeHolder, null); } /** * Create a new {@link BasicCassandraPersistentProperty}. * - * @param field the actual {@link Field} in the domain entity corresponding to this persistent entity. - * @param propertyDescriptor a {@link PropertyDescriptor} for the corresponding property in the domain entity. + * @param property the actual {@link Property} in the domain entity corresponding to this persistent entity. * @param owner the containing object or {@link CassandraPersistentEntity} of this persistent property. * @param simpleTypeHolder mapping of Java [simple|wrapper] types to Cassandra data types. * @param userTypeResolver resolver for user-defined types. */ - public BasicCassandraPersistentProperty(Field field, PropertyDescriptor propertyDescriptor, - CassandraPersistentEntity owner, CassandraSimpleTypeHolder simpleTypeHolder, - UserTypeResolver userTypeResolver) { + public BasicCassandraPersistentProperty(Property property, CassandraPersistentEntity owner, + CassandraSimpleTypeHolder simpleTypeHolder, UserTypeResolver userTypeResolver) { - super(field, propertyDescriptor, owner, simpleTypeHolder); + super(property, owner, simpleTypeHolder); this.userTypeResolver = userTypeResolver; @@ -182,11 +178,8 @@ public class BasicCassandraPersistentProperty extends AnnotationBasedPersistentP * @see org.springframework.data.cassandra.mapping.CassandraPersistentProperty#getPrimaryKeyOrdering() */ @Override - public Ordering getPrimaryKeyOrdering() { - - PrimaryKeyColumn primaryKeyColumn = findAnnotation(PrimaryKeyColumn.class); - - return (primaryKeyColumn != null ? primaryKeyColumn.ordering() : null); + public Optional getPrimaryKeyOrdering() { + return findAnnotation(PrimaryKeyColumn.class).map(PrimaryKeyColumn::ordering); } /* (non-Javadoc) @@ -211,10 +204,10 @@ public class BasicCassandraPersistentProperty extends AnnotationBasedPersistentP private DataType findDataType() { - CassandraType cassandraType = findAnnotation(CassandraType.class); + Optional cassandraType = findAnnotation(CassandraType.class); - if (cassandraType != null) { - return getDataTypeFor(cassandraType); + if (cassandraType.isPresent()) { + return getDataTypeFor(cassandraType.get()); } if (isMap()) { @@ -302,9 +295,8 @@ public class BasicCassandraPersistentProperty extends AnnotationBasedPersistentP @Override public boolean isClusterKeyColumn() { - PrimaryKeyColumn primaryKeyColumn = findAnnotation(PrimaryKeyColumn.class); - - return (primaryKeyColumn != null && PrimaryKeyType.CLUSTERED.equals(primaryKeyColumn.type())); + return findAnnotation(PrimaryKeyColumn.class) + .filter(primaryKeyColumn -> PrimaryKeyType.CLUSTERED.equals(primaryKeyColumn.type())).isPresent(); } /* (non-Javadoc) @@ -313,9 +305,8 @@ public class BasicCassandraPersistentProperty extends AnnotationBasedPersistentP @Override public boolean isPartitionKeyColumn() { - PrimaryKeyColumn primaryKeyColumn = findAnnotation(PrimaryKeyColumn.class); - - return (primaryKeyColumn != null && PrimaryKeyType.PARTITIONED.equals(primaryKeyColumn.type())); + return findAnnotation(PrimaryKeyColumn.class) + .filter(primaryKeyColumn -> PrimaryKeyType.PARTITIONED.equals(primaryKeyColumn.type())).isPresent(); } /* (non-Javadoc) @@ -341,10 +332,14 @@ public class BasicCassandraPersistentProperty extends AnnotationBasedPersistentP protected DataType getDataTypeFor(Class javaType) { - CassandraPersistentEntity persistentEntity = getOwner().getMappingContext().getPersistentEntity(javaType); + Optional> optionalEntity = getOwner().getMappingContext() + .getPersistentEntity(javaType); - if (persistentEntity != null && persistentEntity.isUserDefinedType()) { - return persistentEntity.getUserType(); + Optional> udtEntity = optionalEntity + .filter(CassandraPersistentEntity::isUserDefinedType); + + if (udtEntity.isPresent()) { + return udtEntity.map(CassandraPersistentEntity::getUserType).get(); } DataType dataType = CassandraSimpleTypeHolder.getDataTypeFor(javaType); @@ -389,19 +384,19 @@ public class BasicCassandraPersistentProperty extends AnnotationBasedPersistentP boolean forceQuote; if (isIdProperty()) { // then the id is of a simple type (since it's not a composite primary key) - PrimaryKey primaryKey = findAnnotation(PrimaryKey.class); - overriddenName = primaryKey == null ? null : primaryKey.value(); - forceQuote = (primaryKey != null && primaryKey.forceQuote()); + Optional optionalPrimaryKey = findAnnotation(PrimaryKey.class); + overriddenName = optionalPrimaryKey.map(PrimaryKey::value).orElse(""); + forceQuote = optionalPrimaryKey.map(PrimaryKey::forceQuote).orElse(false); } else if (isPrimaryKeyColumn()) { // then it's a simple type - PrimaryKeyColumn primaryKeyColumn = findAnnotation(PrimaryKeyColumn.class); - overriddenName = primaryKeyColumn == null ? null : primaryKeyColumn.name(); - forceQuote = (primaryKeyColumn != null && primaryKeyColumn.forceQuote()); + Optional optionalPrimaryKey = findAnnotation(PrimaryKeyColumn.class); + overriddenName = optionalPrimaryKey.map(PrimaryKeyColumn::value).orElse(""); + forceQuote = optionalPrimaryKey.map(PrimaryKeyColumn::forceQuote).orElse(false); } else { // then it's a vanilla column with the assumption that it's mapped to a single column - Column column = findAnnotation(Column.class); - overriddenName = column == null ? null : column.value(); - forceQuote = (column != null && column.forceQuote()); + Optional optionalColumn = findAnnotation(Column.class); + overriddenName = optionalColumn.map(Column::value).orElse(""); + forceQuote = optionalColumn.map(Column::forceQuote).orElse(false); } columnNames.add(createColumnName(defaultName, overriddenName, forceQuote)); @@ -425,15 +420,11 @@ public class BasicCassandraPersistentProperty extends AnnotationBasedPersistentP protected void addCompositePrimaryKeyColumnNames(CassandraPersistentEntity compositePrimaryKeyEntity, final List columnNames) { - compositePrimaryKeyEntity.doWithProperties(new PropertyHandler() { - - @Override - public void doWithPersistentProperty(CassandraPersistentProperty property) { - if (property.isCompositePrimaryKey()) { - addCompositePrimaryKeyColumnNames(property.getCompositePrimaryKeyEntity(), columnNames); - } else { - columnNames.add(property.getColumnName()); - } + compositePrimaryKeyEntity.getPersistentProperties().forEach(property -> { + if (property.isCompositePrimaryKey()) { + addCompositePrimaryKeyColumnNames(property.getCompositePrimaryKeyEntity(), columnNames); + } else { + columnNames.add(property.getColumnName()); } }); } @@ -514,15 +505,15 @@ public class BasicCassandraPersistentProperty extends AnnotationBasedPersistentP Assert.state(mappingContext != null, "CassandraMappingContext needed"); - return mappingContext.getPersistentEntity(getCompositePrimaryKeyTypeInformation()); + return mappingContext.getRequiredPersistentEntity(getCompositePrimaryKeyTypeInformation()); } /* (non-Javadoc) * @see org.springframework.data.mapping.model.AbstractPersistentProperty#getAssociation() */ @Override - public Association getAssociation() { - throw new UnsupportedOperationException("Cassandra does not support associations"); + public Optional> getAssociation() { + return Optional.empty(); } /* (non-Javadoc) diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/mapping/CassandraPersistentEntity.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/mapping/CassandraPersistentEntity.java index 23e9c09cb..0cf83ce8c 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/mapping/CassandraPersistentEntity.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/mapping/CassandraPersistentEntity.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2016 the original author or authors + * Copyright 2013-2017 the original author or authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,7 +30,9 @@ import com.datastax.driver.core.UserType; * * @author Alex Shvid * @author Matthew T. Adams + * @author Mark Paluch */ +// TODO: Not extend MutablePersistentEntity but rather PersistentEntity. public interface CassandraPersistentEntity extends MutablePersistentEntity, ApplicationContextAware { @@ -39,6 +41,7 @@ public interface CassandraPersistentEntity */ boolean isCompositePrimaryKey(); + // TODO: return rather a Stream, rename to "getPrimaryKeyProperties" List getCompositePrimaryKeyProperties(); /** @@ -46,12 +49,18 @@ public interface CassandraPersistentEntity */ CqlIdentifier getTableName(); + /** + * Sets the CQL table name. + * + * @param tableName must not be {@literal null}. + */ void setTableName(CqlIdentifier tableName); - CassandraMappingContext getMappingContext(); - - ApplicationContext getApplicationContext(); - + /** + * Sets whether to enforce quoting when using the {@link #getTableName()} in CQL. + * + * @param forceQuote {@literal true} to enforce quoting; {@literal false} to disable enforced quoting usage. + */ void setForceQuote(boolean forceQuote); /** @@ -67,4 +76,9 @@ public interface CassandraPersistentEntity * @see UserDefinedType */ UserType getUserType(); + + // TODO: Review if that's required or it can be handled in a different way + CassandraMappingContext getMappingContext(); + + ApplicationContext getApplicationContext(); } diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/mapping/CassandraPersistentProperty.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/mapping/CassandraPersistentProperty.java index f9c704b8c..f566f57e7 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/mapping/CassandraPersistentProperty.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/mapping/CassandraPersistentProperty.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2016 the original author or authors + * Copyright 2013-2017 the original author or authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +16,7 @@ package org.springframework.data.cassandra.mapping; import java.util.List; +import java.util.Optional; import org.springframework.cassandra.core.Ordering; import org.springframework.cassandra.core.cql.CqlIdentifier; @@ -78,7 +79,7 @@ public interface CassandraPersistentProperty * The ordering (ascending or descending) for the column. Valid only for primary key columns; returns null for * non-primary key columns. */ - Ordering getPrimaryKeyOrdering(); + Optional getPrimaryKeyOrdering(); /** * The column's data type. Not valid for a composite primary key. diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/mapping/CassandraPersistentPropertyComparator.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/mapping/CassandraPersistentPropertyComparator.java index 2ac86037a..49974e48e 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/mapping/CassandraPersistentPropertyComparator.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/mapping/CassandraPersistentPropertyComparator.java @@ -16,6 +16,7 @@ package org.springframework.data.cassandra.mapping; import java.util.Comparator; +import java.util.Optional; import org.springframework.cassandra.core.cql.CqlIdentifier; @@ -78,8 +79,15 @@ public enum CassandraPersistentPropertyComparator implements Comparator optionalLeftAnnotation = left.findAnnotation(PrimaryKeyColumn.class); + Optional optionaRightAnnotation = right.findAnnotation(PrimaryKeyColumn.class); + + return optionalLeftAnnotation.map(leftAnnotation -> { + return optionaRightAnnotation.map(rightAnnotation -> CassandraPrimaryKeyColumnAnnotationComparator.INSTANCE + .compare(leftAnnotation, rightAnnotation)).orElse(0); + + }).orElse(0); } boolean leftIsKey = leftIsCompositePrimaryKey || leftIsPrimaryKey; diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/mapping/CassandraUserTypePersistentEntity.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/mapping/CassandraUserTypePersistentEntity.java index c9b3728e8..9b76442e7 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/mapping/CassandraUserTypePersistentEntity.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/mapping/CassandraUserTypePersistentEntity.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 the original author or authors. + * Copyright 2016-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ */ package org.springframework.data.cassandra.mapping; +import java.util.Optional; + import org.springframework.cassandra.core.cql.CqlIdentifier; import org.springframework.data.mapping.model.MappingException; import org.springframework.data.util.TypeInformation; @@ -61,8 +63,10 @@ public class CassandraUserTypePersistentEntity extends BasicCassandraPersiste */ @Override protected CqlIdentifier determineTableName() { - UserDefinedType typeAnnotation = findAnnotation(UserDefinedType.class); - return determineName(typeAnnotation.value(), typeAnnotation.forceQuote()); + + Optional typeAnnotation = findAnnotation(UserDefinedType.class); + return typeAnnotation.map(userDefinedType -> determineName(userDefinedType.value(), userDefinedType.forceQuote())) + .orElseGet(super::determineDefaultName); } /* (non-Javadoc) diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/mapping/PrimaryKeyClassEntityMetadataVerifier.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/mapping/PrimaryKeyClassEntityMetadataVerifier.java index 9af9cee4b..41a9dc7e3 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/mapping/PrimaryKeyClassEntityMetadataVerifier.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/mapping/PrimaryKeyClassEntityMetadataVerifier.java @@ -19,7 +19,6 @@ import java.util.ArrayList; import java.util.List; import org.springframework.data.annotation.Id; -import org.springframework.data.mapping.PropertyHandler; import org.springframework.data.mapping.model.MappingException; /** @@ -53,58 +52,56 @@ public class PrimaryKeyClassEntityMetadataVerifier implements CassandraPersisten Class entityType = entity.getType(); // Ensure entity is not both a @Table(@Persistent) and a @PrimaryKey - if (entity.findAnnotation(Table.class) != null) { + if (entity.findAnnotation(Table.class).isPresent()) { exceptions.add(new MappingException(String.format("Entity cannot be of type @%s and @%s", - Table.class.getSimpleName(), PrimaryKeyClass.class.getSimpleName()))); + Table.class.getSimpleName(), PrimaryKeyClass.class.getSimpleName()))); } // Ensure PrimaryKeyClass only extends Object if (!entityType.getSuperclass().equals(Object.class)) { - exceptions.add(new MappingException(String.format("@%s must only extend Object", - PrimaryKeyClass.class.getSimpleName()))); + exceptions.add( + new MappingException(String.format("@%s must only extend Object", PrimaryKeyClass.class.getSimpleName()))); } - entity.doWithProperties(new PropertyHandler() { - - @Override - public void doWithPersistentProperty(CassandraPersistentProperty property) { - if (property.isCompositePrimaryKey()) { - compositePrimaryKeys.add(property); - } else if (property.isIdProperty()) { - idProperties.add(property); - } else if (property.isClusterKeyColumn()) { - primaryKeyColumns.add(property); - } else if (property.isPartitionKeyColumn()) { - partitionKeyColumns.add(property); - primaryKeyColumns.add(property); - } + entity.getPersistentProperties().forEach(property -> { + if (property.isCompositePrimaryKey()) { + compositePrimaryKeys.add(property); + } else if (property.isIdProperty()) { + idProperties.add(property); + } else if (property.isClusterKeyColumn()) { + primaryKeyColumns.add(property); + } else if (property.isPartitionKeyColumn()) { + partitionKeyColumns.add(property); + primaryKeyColumns.add(property); } }); - if (!compositePrimaryKeys.isEmpty()) { - exceptions.add(new MappingException( - "Composite primary keys are not allowed inside of composite primary key classes")); + if (!compositePrimaryKeys.isEmpty()) + + { + exceptions + .add(new MappingException("Composite primary keys are not allowed inside of composite primary key classes")); } // Must have at least 1 attribute annotated with @PrimaryKeyColumn if (primaryKeyColumns.isEmpty()) { - exceptions.add(new MappingException(String.format( - "Composite primary key type [%1$s] has no fields annotated with @%2$s", - entity.getType().getName(), PrimaryKeyColumn.class.getSimpleName()))); + exceptions.add( + new MappingException(String.format("Composite primary key type [%1$s] has no fields annotated with @%2$s", + entity.getType().getName(), PrimaryKeyColumn.class.getSimpleName()))); } // At least one of the PrimaryKeyColumns must have a type PARTIONED if (partitionKeyColumns.isEmpty()) { - exceptions.add(new MappingException(String.format( - "At least one of the @%s annotations must have a type of PARTITIONED", - PrimaryKeyColumn.class.getSimpleName()))); + exceptions + .add(new MappingException(String.format("At least one of the @%s annotations must have a type of PARTITIONED", + PrimaryKeyColumn.class.getSimpleName()))); } // Cannot have any Id or PrimaryKey Annotations if (!idProperties.isEmpty()) { - exceptions.add(new MappingException(String.format( - "Annotations @%1$s and @%2$s are invalid for type annotated with @%3$s", - Id.class.getSimpleName(), PrimaryKey.class.getSimpleName(), PrimaryKeyClass.class.getSimpleName()))); + exceptions.add( + new MappingException(String.format("Annotations @%1$s and @%2$s are invalid for type annotated with @%3$s", + Id.class.getSimpleName(), PrimaryKey.class.getSimpleName(), PrimaryKeyClass.class.getSimpleName()))); } // Determine whether or not to throw Exception based on errors found diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/cdi/CassandraRepositoryBean.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/cdi/CassandraRepositoryBean.java index a01178990..0f0ff4dd2 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/cdi/CassandraRepositoryBean.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/cdi/CassandraRepositoryBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2014 the original author or authors. + * Copyright 2014-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ package org.springframework.data.cassandra.repository.cdi; import java.lang.annotation.Annotation; +import java.util.Optional; import java.util.Set; import javax.enterprise.context.spi.CreationalContext; @@ -45,11 +46,11 @@ public class CassandraRepositoryBean extends CdiRepositoryBean { * @param qualifiers must not be {@literal null}. * @param repositoryType must not be {@literal null}. * @param beanManager must not be {@literal null}. - * @param detector detector for the custom {@link org.springframework.data.repository.Repository} implementations - * {@link CustomRepositoryImplementationDetector}, can be {@literal null}. + * @param detector optional detector for the custom {@link org.springframework.data.repository.Repository} + * implementations {@link CustomRepositoryImplementationDetector}, can be {@literal null}. */ public CassandraRepositoryBean(Bean operations, Set qualifiers, - Class repositoryType, BeanManager beanManager, CustomRepositoryImplementationDetector detector) { + Class repositoryType, BeanManager beanManager, Optional detector) { super(qualifiers, repositoryType, beanManager, detector); Assert.notNull(operations, "Cannot create repository with 'null' for CassandraOperations."); @@ -58,12 +59,19 @@ public class CassandraRepositoryBean extends CdiRepositoryBean { /* * (non-Javadoc) - * @see org.springframework.data.repository.cdi.CdiRepositoryBean#create(javax.enterprise.context.spi.CreationalContext, java.lang.Class, java.lang.Object) + * @see org.springframework.data.repository.cdi.CdiRepositoryBean#create(javax.enterprise.context.spi.CreationalContext, java.lang.Class, java.util.Optional) */ @Override - protected T create(CreationalContext creationalContext, Class repositoryType, Object customImplementation) { + protected T create(CreationalContext creationalContext, Class repositoryType, + Optional customImplementation) { CassandraOperations cassandraOperations = getDependencyInstance(cassandraOperationsBean, CassandraOperations.class); - return new CassandraRepositoryFactory(cassandraOperations).getRepository(repositoryType, customImplementation); + + if (customImplementation.isPresent()) { + return new CassandraRepositoryFactory(cassandraOperations).getRepository(repositoryType, + customImplementation.get()); + } + + return new CassandraRepositoryFactory(cassandraOperations).getRepository(repositoryType); } @Override diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/cdi/CassandraRepositoryExtension.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/cdi/CassandraRepositoryExtension.java index a9cd0c9d5..fa6c1812d 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/cdi/CassandraRepositoryExtension.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/cdi/CassandraRepositoryExtension.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2016 the original author or authors. + * Copyright 2014-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,17 +15,19 @@ */ package org.springframework.data.cassandra.repository.cdi; +import java.lang.annotation.Annotation; +import java.lang.reflect.Type; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; +import java.util.Set; + import javax.enterprise.event.Observes; import javax.enterprise.inject.UnsatisfiedResolutionException; import javax.enterprise.inject.spi.AfterBeanDiscovery; import javax.enterprise.inject.spi.Bean; import javax.enterprise.inject.spi.BeanManager; import javax.enterprise.inject.spi.ProcessBean; -import java.lang.annotation.Annotation; -import java.lang.reflect.Type; -import java.util.HashMap; -import java.util.Map; -import java.util.Set; import org.springframework.data.cassandra.core.CassandraOperations; import org.springframework.data.repository.cdi.CdiRepositoryBean; @@ -88,15 +90,12 @@ public class CassandraRepositoryExtension extends CdiRepositoryExtensionSupport private CdiRepositoryBean createRepositoryBean(Class repositoryType, Set qualifiers, BeanManager beanManager) { - Bean cassandraOperationsBean = this.cassandraOperationsMap.get(qualifiers); - if (cassandraOperationsBean == null) { - throw new UnsatisfiedResolutionException(String.format("Unable to resolve a bean for '%s' with qualifiers %s.", - CassandraOperations.class.getName(), qualifiers)); - } + Bean cassandraOperationsBean = Optional.ofNullable(this.cassandraOperationsMap.get(qualifiers)).orElseThrow(() -> new UnsatisfiedResolutionException(String.format("Unable to resolve a bean for '%s' with qualifiers %s.", + CassandraOperations.class.getName(), qualifiers))); return new CassandraRepositoryBean(cassandraOperationsBean, qualifiers, repositoryType, beanManager, - getCustomImplementationDetector()); + Optional.of(getCustomImplementationDetector())); } } 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 932e54758..5f208fb1d 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 @@ -1,5 +1,5 @@ /* - * Copyright 2010-2016 the original author or authors. + * Copyright 2010-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -100,6 +100,7 @@ public abstract class AbstractCassandraQuery implements RepositoryQuery { CassandraParameterAccessor parameterAccessor = new ConvertingParameterAccessor(template.getConverter(), new CassandraParametersParameterAccessor(queryMethod, parameters)); + // FIXME: Use ResultProcessor#withDynamicProjection(ParameterAccessor) when available ResultProcessor resultProcessor = queryMethod.getResultProcessor().withDynamicProjection(parameterAccessor); String query = createQuery(parameterAccessor); 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 bfa430836..e93b15c3b 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 @@ -1,5 +1,5 @@ /* - * Copyright 2016 the original author or authors. + * Copyright 2016-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -88,27 +88,27 @@ public abstract class AbstractReactiveCassandraQuery implements RepositoryQuery ReactiveCassandraParameterAccessor accessor = new ReactiveCassandraParameterAccessor(method, parameters); - return (getQueryMethod().isCollectionQuery() ? Flux.defer(() -> (Publisher) execute(accessor)) + return (getQueryMethod().isCollectionQuery() ? Flux.defer(() -> (Publisher) execute(accessor)) : Mono.defer(() -> (Mono) execute(accessor))); } private Object execute(CassandraParameterAccessor parameterAccessor) { - CassandraParameterAccessor convertingParameterAccessor = - new ConvertingParameterAccessor(operations.getConverter(), parameterAccessor); + CassandraParameterAccessor convertingParameterAccessor = new ConvertingParameterAccessor(operations.getConverter(), + parameterAccessor); String query = createQuery(convertingParameterAccessor); + // FIXME: Use ResultProcessor#withDynamicProjection(ParameterAccessor) when available ResultProcessor resultProcessor = method.getResultProcessor().withDynamicProjection(convertingParameterAccessor); - ReactiveCassandraQueryExecution queryExecution = getExecution(new ResultProcessingConverter( - resultProcessor, operations.getConverter().getMappingContext(), instantiators)); + ReactiveCassandraQueryExecution queryExecution = getExecution( + new ResultProcessingConverter(resultProcessor, operations.getConverter().getMappingContext(), instantiators)); CassandraReturnedType returnedType = new CassandraReturnedType(resultProcessor.getReturnedType(), operations.getConverter().getCustomConversions()); - Class resultType = (returnedType.isProjecting() ? returnedType.getDomainType() - : returnedType.getReturnedType()); + Class resultType = (returnedType.isProjecting() ? returnedType.getDomainType() : returnedType.getReturnedType()); return queryExecution.execute(query, resultType); } diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/CassandraQueryCreator.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/CassandraQueryCreator.java index e5850bb50..892702f80 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/CassandraQueryCreator.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/CassandraQueryCreator.java @@ -19,6 +19,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.List; +import java.util.Optional; import java.util.regex.Pattern; import org.slf4j.Logger; @@ -82,7 +83,7 @@ class CassandraQueryCreator extends AbstractQueryCreator { Assert.notNull(entityMetadata, "CassandraEntityMetadata must not be null"); this.mappingContext = mappingContext; - this.entity = mappingContext.getPersistentEntity(entityMetadata.getJavaType()); + this.entity = mappingContext.getRequiredPersistentEntity(entityMetadata.getJavaType()); this.tableName = entityMetadata.getTableName(); } @@ -92,8 +93,8 @@ class CassandraQueryCreator extends AbstractQueryCreator { @Override protected Clause create(Part part, Iterator iterator) { - PersistentPropertyPath path = - mappingContext.getPersistentPropertyPath(part.getProperty()); + PersistentPropertyPath path = mappingContext + .getPersistentPropertyPath(part.getProperty()); CassandraPersistentProperty property = path.getLeafProperty(); @@ -175,8 +176,8 @@ class CassandraQueryCreator extends AbstractQueryCreator { case SIMPLE_PROPERTY: return QueryBuilder.eq(columnName(property), parameters.nextConverted(property)); default: - throw new InvalidDataAccessApiUsageException(String.format( - "Unsupported keyword [%s] in part [%s]", type, part)); + throw new InvalidDataAccessApiUsageException( + String.format("Unsupported keyword [%s] in part [%s]", type, part)); } } @@ -258,7 +259,8 @@ class CassandraQueryCreator extends AbstractQueryCreator { * Build a {@link Select} statement from the given {@link WhereBuilder} and {@link Sort}. Resolves property names * for {@link Sort} using the {@link CassandraPersistentEntity}. */ - static Select select(CassandraPersistentEntity entity, CqlIdentifier tableName, WhereBuilder whereBuilder, Sort sort) { + static Select select(CassandraPersistentEntity entity, CqlIdentifier tableName, WhereBuilder whereBuilder, + Sort sort) { Select select = QueryBuilder.select().from(tableName.toCql()); @@ -281,28 +283,28 @@ class CassandraQueryCreator extends AbstractQueryCreator { return select; } + @SuppressWarnings("unchecked") private static CassandraPersistentProperty getPersistentProperty(CassandraPersistentEntity entity, String dotPath) { String[] segments = PUNCTUATION_PATTERN.split(dotPath); - CassandraPersistentProperty property = null; + Optional property = Optional.empty(); CassandraPersistentEntity currentEntity = entity; for (String segment : segments) { + property = currentEntity.getPersistentProperty(segment); + currentEntity = property // + .filter(CassandraPersistentProperty::isCompositePrimaryKey) // + .map(CassandraPersistentProperty::getCompositePrimaryKeyEntity) // + .orElse((CassandraPersistentEntity) entity); - if (property != null && property.isCompositePrimaryKey()) { - currentEntity = property.getCompositePrimaryKeyEntity(); - } } - if (property != null) { - return property; - } + return property.orElseThrow(() -> new IllegalArgumentException( + String.format("Cannot resolve path [%s] to a property of [%s]", dotPath, entity.getName()))); - throw new IllegalArgumentException(String.format( - "Cannot resolve path [%s] to a property of [%s]", dotPath, entity.getName())); } } } 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 92c3c15cf..766b9f715 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 @@ -16,6 +16,9 @@ package org.springframework.data.cassandra.repository.query; +import lombok.NonNull; +import lombok.RequiredArgsConstructor; + import org.springframework.core.convert.converter.Converter; import org.springframework.data.cassandra.core.CassandraOperations; import org.springframework.data.cassandra.mapping.CassandraMappingContext; @@ -24,9 +27,6 @@ import org.springframework.data.repository.query.ResultProcessor; import org.springframework.data.repository.query.ReturnedType; import org.springframework.util.ClassUtils; -import lombok.NonNull; -import lombok.RequiredArgsConstructor; - /** * Query executions for Cassandra. * diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/CassandraQueryMethod.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/CassandraQueryMethod.java index 758872f41..0175ef3a7 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/CassandraQueryMethod.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/CassandraQueryMethod.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 the original author or authors. + * Copyright 2016-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +16,7 @@ package org.springframework.data.cassandra.repository.query; import java.lang.reflect.Method; +import java.util.Optional; import org.springframework.core.annotation.AnnotatedElementUtils; import org.springframework.core.annotation.AnnotationUtils; @@ -97,14 +98,16 @@ public class CassandraQueryMethod extends QueryMethod { if (ClassUtils.isPrimitiveOrWrapper(returnedObjectType)) { this.entityMetadata = new SimpleCassandraEntityMetadata((Class) domainClass, - mappingContext.getPersistentEntity(domainClass)); + mappingContext.getRequiredPersistentEntity(domainClass)); } else { - CassandraPersistentEntity returnedEntity = mappingContext.getPersistentEntity(returnedObjectType); - CassandraPersistentEntity managedEntity = mappingContext.getPersistentEntity(domainClass); - returnedEntity = (returnedEntity == null || returnedEntity.getType().isInterface() ? managedEntity - : returnedEntity); + Optional> optionalReturnedEntity = mappingContext + .getPersistentEntity(returnedObjectType); + CassandraPersistentEntity managedEntity = mappingContext.getRequiredPersistentEntity(domainClass); + + CassandraPersistentEntity returnedEntity = optionalReturnedEntity.filter(e -> !e.getType().isInterface()) + .orElse(managedEntity); // TODO collectionEntity? CassandraPersistentEntity collectionEntity = domainClass.isAssignableFrom(returnedObjectType) @@ -112,6 +115,7 @@ public class CassandraQueryMethod extends QueryMethod { this.entityMetadata = new SimpleCassandraEntityMetadata((Class) returnedEntity.getType(), collectionEntity); + } } diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/ConvertingParameterAccessor.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/ConvertingParameterAccessor.java index 3b8332da2..a2bc59dbd 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/ConvertingParameterAccessor.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/ConvertingParameterAccessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 the original author or authors. + * Copyright 2016-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +16,7 @@ package org.springframework.data.cassandra.repository.query; import java.util.Iterator; +import java.util.Optional; import java.util.Set; import org.springframework.data.cassandra.convert.CassandraConverter; @@ -25,6 +26,7 @@ import org.springframework.data.cassandra.mapping.CassandraSimpleTypeHolder; import org.springframework.data.cassandra.mapping.CassandraType; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; +import org.springframework.data.mapping.PersistentProperty; import org.springframework.data.util.ClassTypeInformation; import org.springframework.data.util.TypeInformation; @@ -74,7 +76,7 @@ class ConvertingParameterAccessor implements CassandraParameterAccessor { * @see org.springframework.data.repository.query.ParameterAccessor#getDynamicProjection() */ @Override - public Class getDynamicProjection() { + public Optional> getDynamicProjection() { return delegate.getDynamicProjection(); } @@ -83,7 +85,7 @@ class ConvertingParameterAccessor implements CassandraParameterAccessor { */ @Override public Object getBindableValue(int index) { - return potentiallyConvert(index, delegate.getBindableValue(index), null); + return potentiallyConvert(index, Optional.ofNullable(delegate.getBindableValue(index))); } /* (non-Javadoc) @@ -137,14 +139,24 @@ class ConvertingParameterAccessor implements CassandraParameterAccessor { } @SuppressWarnings("unchecked") - private Object potentiallyConvert(int index, Object bindableValue, CassandraPersistentProperty property) { + private Object potentiallyConvert(int index, Optional bindableValue) { - return (bindableValue == null ? null - : converter.convertToCassandraColumn(bindableValue, findTypeInformation(index, bindableValue, property))); + return bindableValue + .flatMap( + v -> converter.convertToCassandraColumn(bindableValue, findTypeInformation(index, v, Optional.empty()))) + .orElse(null); + } + + @SuppressWarnings("unchecked") + private Object potentiallyConvert(int index, Optional bindableValue, CassandraPersistentProperty property) { + + return bindableValue.flatMap( + v -> converter.convertToCassandraColumn(bindableValue, findTypeInformation(index, v, Optional.of(property)))) + .orElse(null); } private TypeInformation findTypeInformation(int index, Object bindableValue, - CassandraPersistentProperty property) { + Optional property) { if (delegate.findCassandraType(index) != null) { TypeCodec typeCodec = CodecRegistry.DEFAULT_INSTANCE.codecFor(getDataType(index, property)); @@ -156,11 +168,8 @@ class ConvertingParameterAccessor implements CassandraParameterAccessor { return ClassTypeInformation.from(typeCodec.getJavaType().getRawType()); } - if (property == null) { - return ClassTypeInformation.from(bindableValue.getClass()); - } - - return property.getTypeInformation(); + return property.map(PersistentProperty::getTypeInformation) + .orElseGet(() -> (TypeInformation) ClassTypeInformation.from(bindableValue.getClass())); } /** @@ -171,7 +180,7 @@ class ConvertingParameterAccessor implements CassandraParameterAccessor { * @param property {@link CassandraPersistentProperty}. * @return the {@link DataType} */ - DataType getDataType(int index, CassandraPersistentProperty property) { + DataType getDataType(int index, Optional optionalProperty) { CassandraType cassandraType = delegate.findCassandraType(index); @@ -182,9 +191,13 @@ class ConvertingParameterAccessor implements CassandraParameterAccessor { CassandraMappingContext mappingContext = converter.getMappingContext(); TypeInformation typeInformation = ClassTypeInformation.from(getParameterType(index)); - if (property == null) { - return mappingContext.getDataType(typeInformation.getType()); - } + return optionalProperty.map(property -> getDataType(mappingContext, typeInformation, property)) + .orElseGet(() -> mappingContext.getDataType(typeInformation.getType())); + + } + + private DataType getDataType(CassandraMappingContext mappingContext, TypeInformation typeInformation, + CassandraPersistentProperty property) { DataType dataType = mappingContext.getDataType(property); @@ -252,7 +265,7 @@ class ConvertingParameterAccessor implements CassandraParameterAccessor { * @see java.util.Iterator#next() */ public Object next() { - return potentiallyConvert(index++, delegate.next(), null); + return potentiallyConvert(index++, Optional.ofNullable(delegate.next())); } /* @@ -268,7 +281,7 @@ class ConvertingParameterAccessor implements CassandraParameterAccessor { */ @Override public Object nextConverted(CassandraPersistentProperty property) { - return potentiallyConvert(index++, delegate.next(), property); + return potentiallyConvert(index++, Optional.ofNullable(delegate.next()), property); } } diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/DtoInstantiatingConverter.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/DtoInstantiatingConverter.java index 82dbb7e6a..ff850b108 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/DtoInstantiatingConverter.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/DtoInstantiatingConverter.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 the original author or authors. + * Copyright 2016-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,6 +15,8 @@ */ package org.springframework.data.cassandra.repository.query; +import java.util.Optional; + import org.springframework.core.convert.converter.Converter; import org.springframework.data.cassandra.mapping.CassandraPersistentEntity; import org.springframework.data.cassandra.mapping.CassandraPersistentProperty; @@ -38,8 +40,10 @@ import org.springframework.util.Assert; class DtoInstantiatingConverter implements Converter { private final Class targetType; + private final MappingContext, ? extends PersistentProperty> context; - private final EntityInstantiator instantiator; + + private final Optional instantiator; /** * Create a new {@link Converter} to instantiate DTOs. @@ -58,7 +62,8 @@ class DtoInstantiatingConverter implements Converter { this.targetType = dtoType; this.context = context; - this.instantiator = instantiator.getInstantiatorFor(context.getPersistentEntity(dtoType)); + + this.instantiator = context.getPersistentEntity(dtoType).map(instantiator::getInstantiatorFor); } /* @@ -72,35 +77,38 @@ class DtoInstantiatingConverter implements Converter { return source; } - final PersistentEntity sourceEntity = context.getPersistentEntity(source.getClass()); - final PersistentPropertyAccessor sourceAccessor = sourceEntity.getPropertyAccessor(source); - final PersistentEntity targetEntity = context.getPersistentEntity(targetType); + PersistentEntity sourceEntity = context.getRequiredPersistentEntity(source.getClass()); + PersistentPropertyAccessor sourceAccessor = sourceEntity.getPropertyAccessor(source); + PersistentEntity targetEntity = context.getRequiredPersistentEntity(targetType); + + EntityInstantiator instantiator = this.instantiator.orElseThrow( + () -> new IllegalStateException(String.format("No EntityInstantiator for [%s] available", targetType))); @SuppressWarnings({ "rawtypes", "unchecked" }) Object dto = instantiator.createInstance(targetEntity, new ParameterValueProvider() { @Override - public Object getParameterValue(Parameter parameter) { - return sourceAccessor.getProperty(sourceEntity.getPersistentProperty(parameter.getName())); + public Optional getParameterValue(Parameter parameter) { + + // TODO: Fix generics + return parameter.getName() + .flatMap(name -> sourceAccessor.getProperty(sourceEntity.getRequiredPersistentProperty((String) name))); } }); final PersistentPropertyAccessor targetAccessor = targetEntity.getPropertyAccessor(dto); - final PreferredConstructor> constructor = - targetEntity.getPersistenceConstructor(); - targetEntity.doWithProperties(new SimplePropertyHandler() { + Optional>> optionalConstructor = targetEntity + .getPersistenceConstructor(); - @Override - public void doWithPersistentProperty(PersistentProperty property) { + targetEntity.doWithProperties((SimplePropertyHandler) property -> { - if (constructor.isConstructorParameter(property)) { - return; - } - - targetAccessor.setProperty(property, - sourceAccessor.getProperty(sourceEntity.getPersistentProperty(property.getName()))); + if (!optionalConstructor.filter(c -> c.isConstructorParameter(property)).isPresent()) { + return; } + + targetAccessor.setProperty(property, + sourceAccessor.getProperty(sourceEntity.getRequiredPersistentProperty(property.getName()))); }); return dto; diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/ExpressionEvaluatingParameterBinder.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/ExpressionEvaluatingParameterBinder.java index 4b806b56c..fe571de69 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/ExpressionEvaluatingParameterBinder.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/query/ExpressionEvaluatingParameterBinder.java @@ -20,6 +20,7 @@ import java.util.Collections; import java.util.List; import org.springframework.data.repository.query.EvaluationContextProvider; +import org.springframework.data.repository.query.Parameter; import org.springframework.expression.EvaluationContext; import org.springframework.expression.Expression; import org.springframework.expression.spel.standard.SpelExpressionParser; @@ -99,14 +100,14 @@ class ExpressionEvaluatingParameterBinder { private int getParameterIndex(CassandraParameters parameters, String parameterName) { - for (CassandraParameters.CassandraParameter parameter : parameters) { - if (parameterName.equals(parameter.getName())) { - return parameter.getIndex(); - } - } - - throw new IllegalArgumentException( - String.format("Invalid parameter name; Cannot resolve parameter [%s]", parameterName)); + return parameters.stream() // + .filter(cassandraParameter -> cassandraParameter // + .getName().filter(s -> s.equals(parameterName)) // + .isPresent()) // + .mapToInt(Parameter::getIndex) // + .findFirst() // + .orElseThrow(() -> new IllegalArgumentException( + String.format("Invalid parameter name; Cannot resolve parameter [%s]", parameterName))); } /** @@ -117,8 +118,7 @@ class ExpressionEvaluatingParameterBinder { * @param parameterValues must not be {@literal null}. * @return the value of the {@code expressionString} evaluation. */ - private Object evaluateExpression(String expressionString, CassandraParameters parameters, - Object[] parameterValues) { + private Object evaluateExpression(String expressionString, CassandraParameters parameters, Object[] parameterValues) { EvaluationContext evaluationContext = evaluationContextProvider.getEvaluationContext(parameters, parameterValues); Expression expression = expressionParser.parseExpression(expressionString); @@ -139,8 +139,8 @@ class ExpressionEvaluatingParameterBinder { * Creates new {@link BindingContext}. * * @param queryMethod {@link CassandraQueryMethod} on which the parameters are evaluated. - * @param bindings {@link List} of {@link ParameterBinding} containing name or position (index) - * information pertaining to the parameter in the referenced {@code queryMethod}. + * @param bindings {@link List} of {@link ParameterBinding} containing name or position (index) information + * pertaining to the parameter in the referenced {@code queryMethod}. */ public BindingContext(CassandraQueryMethod queryMethod, List bindings) { diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/support/CassandraRepositoryFactory.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/support/CassandraRepositoryFactory.java index 3e2783234..d997d5e8b 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/support/CassandraRepositoryFactory.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/support/CassandraRepositoryFactory.java @@ -17,6 +17,7 @@ package org.springframework.data.cassandra.repository.support; import java.io.Serializable; import java.lang.reflect.Method; +import java.util.Optional; import org.springframework.data.cassandra.core.CassandraOperations; import org.springframework.data.cassandra.mapping.CassandraMappingContext; @@ -26,7 +27,6 @@ import org.springframework.data.cassandra.repository.query.CassandraEntityInform import org.springframework.data.cassandra.repository.query.CassandraQueryMethod; import org.springframework.data.cassandra.repository.query.PartTreeCassandraQuery; import org.springframework.data.cassandra.repository.query.StringBasedCassandraQuery; -import org.springframework.data.mapping.model.MappingException; import org.springframework.data.projection.ProjectionFactory; import org.springframework.data.repository.core.NamedQueries; import org.springframework.data.repository.core.RepositoryInformation; @@ -95,41 +95,34 @@ public class CassandraRepositoryFactory extends RepositoryFactorySupport { @SuppressWarnings("unchecked") public CassandraEntityInformation getEntityInformation(Class domainClass) { - CassandraPersistentEntity entity = mappingContext.getPersistentEntity(domainClass); + CassandraPersistentEntity entity = mappingContext.getRequiredPersistentEntity(domainClass); + - if (entity == null) { - throw new MappingException( - String.format("Could not lookup mapping metadata for domain class %s", domainClass.getName())); - } return new MappingCassandraEntityInformation((CassandraPersistentEntity) entity, operations.getConverter()); } - /* (non-Javadoc) - * @see org.springframework.data.repository.core.support.RepositoryFactorySupport#getQueryLookupStrategy(org.springframework.data.repository.query.QueryLookupStrategy.Key) + /* + * (non-Javadoc) + * @see org.springframework.data.repository.core.support.RepositoryFactorySupport#getQueryLookupStrategy(Key, EvaluationContextProvider) */ @Override - protected QueryLookupStrategy getQueryLookupStrategy(Key key) { - return getQueryLookupStrategy(key, null); - } - - /* (non-Javadoc) - * @see org.springframework.data.repository.core.support.RepositoryFactorySupport#getQueryLookupStrategy(org.springframework.data.repository.query.QueryLookupStrategy.Key, org.springframework.data.repository.query.EvaluationContextProvider) - */ - @Override - protected QueryLookupStrategy getQueryLookupStrategy(Key key, EvaluationContextProvider evaluationContextProvider) { - return new CassandraQueryLookupStrategy(operations, evaluationContextProvider, mappingContext); + protected Optional getQueryLookupStrategy(Key key, + EvaluationContextProvider evaluationContextProvider) { + return Optional.of(new CassandraQueryLookupStrategy(operations, evaluationContextProvider, mappingContext)); } private class CassandraQueryLookupStrategy implements QueryLookupStrategy { private final EvaluationContextProvider evaluationContextProvider; + private final CassandraMappingContext mappingContext; + private final CassandraOperations operations; - public CassandraQueryLookupStrategy(CassandraOperations operations, - EvaluationContextProvider evaluationContextProvider, CassandraMappingContext mappingContext) { + CassandraQueryLookupStrategy(CassandraOperations operations, EvaluationContextProvider evaluationContextProvider, + CassandraMappingContext mappingContext) { this.operations = operations; this.evaluationContextProvider = evaluationContextProvider; diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/support/MappingCassandraEntityInformation.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/support/MappingCassandraEntityInformation.java index d5be8f7dd..65e5c66d2 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/support/MappingCassandraEntityInformation.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/support/MappingCassandraEntityInformation.java @@ -16,6 +16,7 @@ package org.springframework.data.cassandra.repository.support; import java.io.Serializable; +import java.util.Optional; import org.springframework.cassandra.core.cql.CqlIdentifier; import org.springframework.data.cassandra.convert.CassandraConverter; @@ -58,17 +59,15 @@ public class MappingCassandraEntityInformation exten */ @SuppressWarnings("unchecked") @Override - public ID getId(T entity) { + public Optional getId(T entity) { Assert.notNull(entity, "Entity must not be null"); - CassandraPersistentProperty idProperty = entityMetadata.getIdProperty(); + Optional idProperty = entityMetadata.getIdProperty(); - if (idProperty != null) { - return (ID) entityMetadata.getIdentifierAccessor(entity).getIdentifier(); - } - - return (ID) converter.getId(entity, entityMetadata); + // FIXME: Cast + return idProperty.map(p -> entityMetadata.getIdentifierAccessor(entity).getIdentifier()) + .orElseGet(() -> Optional.ofNullable(converter.getId(entity, entityMetadata))).map(o -> (ID) o); } /* (non-Javadoc) @@ -77,8 +76,7 @@ public class MappingCassandraEntityInformation exten @SuppressWarnings("unchecked") @Override public Class getIdType() { - return (Class) (entityMetadata.getIdProperty() == null ? MapId.class - : entityMetadata.getIdProperty().getType()); + return entityMetadata.getIdProperty().map(p -> (Class) p.getType()).orElse((Class) MapId.class); } /* (non-Javadoc) diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/support/ReactiveCassandraRepositoryFactory.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/support/ReactiveCassandraRepositoryFactory.java index 36997baec..12a28af19 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/support/ReactiveCassandraRepositoryFactory.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/support/ReactiveCassandraRepositoryFactory.java @@ -17,6 +17,7 @@ package org.springframework.data.cassandra.repository.support; import java.io.Serializable; import java.lang.reflect.Method; +import java.util.Optional; import org.springframework.data.cassandra.core.ReactiveCassandraOperations; import org.springframework.data.cassandra.mapping.CassandraMappingContext; @@ -25,7 +26,6 @@ import org.springframework.data.cassandra.repository.query.CassandraEntityInform import org.springframework.data.cassandra.repository.query.ReactiveCassandraQueryMethod; import org.springframework.data.cassandra.repository.query.ReactivePartTreeCassandraQuery; import org.springframework.data.cassandra.repository.query.ReactiveStringBasedCassandraQuery; -import org.springframework.data.mapping.model.MappingException; import org.springframework.data.projection.ProjectionFactory; import org.springframework.data.repository.core.NamedQueries; import org.springframework.data.repository.core.RepositoryInformation; @@ -88,8 +88,9 @@ public class ReactiveCassandraRepositoryFactory extends ReactiveRepositoryFactor * @see org.springframework.data.repository.core.support.RepositoryFactorySupport#getQueryLookupStrategy(org.springframework.data.repository.query.QueryLookupStrategy.Key, org.springframework.data.repository.query.EvaluationContextProvider) */ @Override - protected QueryLookupStrategy getQueryLookupStrategy(Key key, EvaluationContextProvider evaluationContextProvider) { - return new CassandraQueryLookupStrategy(operations, evaluationContextProvider, mappingContext); + protected Optional getQueryLookupStrategy(Key key, + EvaluationContextProvider evaluationContextProvider) { + return Optional.of(new CassandraQueryLookupStrategy(operations, evaluationContextProvider, mappingContext)); } /* (non-Javadoc) @@ -97,12 +98,8 @@ public class ReactiveCassandraRepositoryFactory extends ReactiveRepositoryFactor */ @SuppressWarnings("unchecked") public CassandraEntityInformation getEntityInformation(Class domainClass) { - CassandraPersistentEntity entity = mappingContext.getPersistentEntity(domainClass); - if (entity == null) { - throw new MappingException( - String.format("Could not lookup mapping metadata for domain class %s!", domainClass.getName())); - } + CassandraPersistentEntity entity = mappingContext.getRequiredPersistentEntity(domainClass); return new MappingCassandraEntityInformation<>((CassandraPersistentEntity) entity, operations.getConverter()); } diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/support/SimpleCassandraRepository.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/support/SimpleCassandraRepository.java index 32426b3f7..c87c52a44 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/support/SimpleCassandraRepository.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/repository/support/SimpleCassandraRepository.java @@ -18,6 +18,7 @@ package org.springframework.data.cassandra.repository.support; import java.io.Serializable; import java.util.ArrayList; import java.util.List; +import java.util.Optional; import org.springframework.data.cassandra.core.CassandraOperations; import org.springframework.data.cassandra.core.CassandraTemplate; @@ -81,6 +82,7 @@ public class SimpleCassandraRepository implements Ty for (S entity : entities) { S saved; + if (entityInformation.isNew(entity)) { saved = operations.insert(entity); } else { @@ -132,11 +134,11 @@ public class SimpleCassandraRepository implements Ty * @see org.springframework.data.repository.CrudRepository#findOne(java.io.Serializable) */ @Override - public T findOne(ID id) { + public Optional findOne(ID id) { Assert.notNull(id, "The given id must not be null"); - return operations.selectOneById(id, entityInformation.getJavaType()); + return Optional.ofNullable(operations.selectOneById(id, entityInformation.getJavaType())); } /* (non-Javadoc) @@ -199,7 +201,8 @@ public class SimpleCassandraRepository implements Ty Assert.notNull(entity, "The given entity must not be null"); - delete(entityInformation.getId(entity)); + delete(entityInformation.getId(entity) + .orElseThrow(() -> new IllegalArgumentException(String.format("Cannot obtain Id from [%s]", entity)))); } /* (non-Javadoc) diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/convert/CassandraTypeMappingIntegrationTest.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/convert/CassandraTypeMappingIntegrationTest.java index 8973416db..f854e7bbb 100755 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/convert/CassandraTypeMappingIntegrationTest.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/convert/CassandraTypeMappingIntegrationTest.java @@ -71,7 +71,7 @@ public class CassandraTypeMappingIntegrationTest extends AbstractKeyspaceCreatin entity.setInet(InetAddress.getByName("127.0.0.1")); operations.insert(entity); - AllPossibleTypes loaded = operations.selectOneById(entity.getId(), AllPossibleTypes.class); + AllPossibleTypes loaded = load(entity); assertThat(loaded.getInet()).isEqualTo(entity.getInet()); } @@ -83,7 +83,7 @@ public class CassandraTypeMappingIntegrationTest extends AbstractKeyspaceCreatin entity.setUuid(UUID.randomUUID()); operations.insert(entity); - AllPossibleTypes loaded = operations.selectOneById(entity.getId(), AllPossibleTypes.class); + AllPossibleTypes loaded = load(entity); assertThat(loaded.getUuid()).isEqualTo(entity.getUuid()); } @@ -95,7 +95,7 @@ public class CassandraTypeMappingIntegrationTest extends AbstractKeyspaceCreatin entity.setBoxedShort(Short.MAX_VALUE); operations.insert(entity); - AllPossibleTypes loaded = operations.selectOneById(entity.getId(), AllPossibleTypes.class); + AllPossibleTypes loaded = load(entity); assertThat(loaded.getBoxedShort()).isEqualTo(entity.getBoxedShort()); } @@ -107,7 +107,7 @@ public class CassandraTypeMappingIntegrationTest extends AbstractKeyspaceCreatin entity.setPrimitiveShort(Short.MAX_VALUE); operations.insert(entity); - AllPossibleTypes loaded = operations.selectOneById(entity.getId(), AllPossibleTypes.class); + AllPossibleTypes loaded = load(entity); assertThat(loaded.getPrimitiveShort()).isEqualTo(entity.getPrimitiveShort()); } @@ -119,7 +119,7 @@ public class CassandraTypeMappingIntegrationTest extends AbstractKeyspaceCreatin entity.setBoxedByte(Byte.MAX_VALUE); operations.insert(entity); - AllPossibleTypes loaded = operations.selectOneById(entity.getId(), AllPossibleTypes.class); + AllPossibleTypes loaded = load(entity); assertThat(loaded.getBoxedByte()).isEqualTo(entity.getBoxedByte()); } @@ -131,7 +131,7 @@ public class CassandraTypeMappingIntegrationTest extends AbstractKeyspaceCreatin entity.setPrimitiveByte(Byte.MAX_VALUE); operations.insert(entity); - AllPossibleTypes loaded = operations.selectOneById(entity.getId(), AllPossibleTypes.class); + AllPossibleTypes loaded = load(entity); assertThat(loaded.getPrimitiveByte()).isEqualTo(entity.getPrimitiveByte()); } @@ -143,7 +143,7 @@ public class CassandraTypeMappingIntegrationTest extends AbstractKeyspaceCreatin entity.setBoxedLong(Long.MAX_VALUE); operations.insert(entity); - AllPossibleTypes loaded = operations.selectOneById(entity.getId(), AllPossibleTypes.class); + AllPossibleTypes loaded = load(entity); assertThat(loaded.getBoxedLong()).isEqualTo(entity.getBoxedLong()); } @@ -155,7 +155,7 @@ public class CassandraTypeMappingIntegrationTest extends AbstractKeyspaceCreatin entity.setPrimitiveLong(Long.MAX_VALUE); operations.insert(entity); - AllPossibleTypes loaded = operations.selectOneById(entity.getId(), AllPossibleTypes.class); + AllPossibleTypes loaded = load(entity); assertThat(loaded.getPrimitiveLong()).isEqualTo(entity.getPrimitiveLong()); } @@ -167,7 +167,7 @@ public class CassandraTypeMappingIntegrationTest extends AbstractKeyspaceCreatin entity.setBoxedInteger(Integer.MAX_VALUE); operations.insert(entity); - AllPossibleTypes loaded = operations.selectOneById(entity.getId(), AllPossibleTypes.class); + AllPossibleTypes loaded = load(entity); assertThat(loaded.getBoxedInteger()).isEqualTo(entity.getBoxedInteger()); } @@ -179,7 +179,7 @@ public class CassandraTypeMappingIntegrationTest extends AbstractKeyspaceCreatin entity.setPrimitiveInteger(Integer.MAX_VALUE); operations.insert(entity); - AllPossibleTypes loaded = operations.selectOneById(entity.getId(), AllPossibleTypes.class); + AllPossibleTypes loaded = load(entity); assertThat(loaded.getPrimitiveInteger()).isEqualTo(entity.getPrimitiveInteger()); } @@ -191,7 +191,7 @@ public class CassandraTypeMappingIntegrationTest extends AbstractKeyspaceCreatin entity.setBoxedFloat(Float.MAX_VALUE); operations.insert(entity); - AllPossibleTypes loaded = operations.selectOneById(entity.getId(), AllPossibleTypes.class); + AllPossibleTypes loaded = load(entity); assertThat(loaded.getBoxedFloat()).isEqualTo(entity.getBoxedFloat()); } @@ -203,7 +203,7 @@ public class CassandraTypeMappingIntegrationTest extends AbstractKeyspaceCreatin entity.setPrimitiveFloat(Float.MAX_VALUE); operations.insert(entity); - AllPossibleTypes loaded = operations.selectOneById(entity.getId(), AllPossibleTypes.class); + AllPossibleTypes loaded = load(entity); assertThat(loaded.getPrimitiveFloat()).isEqualTo(entity.getPrimitiveFloat()); } @@ -215,7 +215,7 @@ public class CassandraTypeMappingIntegrationTest extends AbstractKeyspaceCreatin entity.setBoxedDouble(Double.MAX_VALUE); operations.insert(entity); - AllPossibleTypes loaded = operations.selectOneById(entity.getId(), AllPossibleTypes.class); + AllPossibleTypes loaded = load(entity); assertThat(loaded.getBoxedDouble()).isEqualTo(entity.getBoxedDouble()); } @@ -227,7 +227,7 @@ public class CassandraTypeMappingIntegrationTest extends AbstractKeyspaceCreatin entity.setPrimitiveDouble(Double.MAX_VALUE); operations.insert(entity); - AllPossibleTypes loaded = operations.selectOneById(entity.getId(), AllPossibleTypes.class); + AllPossibleTypes loaded = load(entity); assertThat(loaded.getPrimitiveDouble()).isEqualTo(entity.getPrimitiveDouble()); } @@ -239,7 +239,7 @@ public class CassandraTypeMappingIntegrationTest extends AbstractKeyspaceCreatin entity.setBoxedBoolean(Boolean.TRUE); operations.insert(entity); - AllPossibleTypes loaded = operations.selectOneById(entity.getId(), AllPossibleTypes.class); + AllPossibleTypes loaded = load(entity); assertThat(loaded.getBoxedBoolean()).isEqualTo(entity.getBoxedBoolean()); } @@ -251,7 +251,7 @@ public class CassandraTypeMappingIntegrationTest extends AbstractKeyspaceCreatin entity.setPrimitiveBoolean(Boolean.TRUE); operations.insert(entity); - AllPossibleTypes loaded = operations.selectOneById(entity.getId(), AllPossibleTypes.class); + AllPossibleTypes loaded = load(entity); assertThat(loaded.isPrimitiveBoolean()).isEqualTo(entity.isPrimitiveBoolean()); } @@ -263,7 +263,7 @@ public class CassandraTypeMappingIntegrationTest extends AbstractKeyspaceCreatin entity.setTimestamp(new Date(1)); operations.insert(entity); - AllPossibleTypes loaded = operations.selectOneById(entity.getId(), AllPossibleTypes.class); + AllPossibleTypes loaded = load(entity); assertThat(loaded.getTimestamp()).isEqualTo(entity.getTimestamp()); } @@ -275,7 +275,7 @@ public class CassandraTypeMappingIntegrationTest extends AbstractKeyspaceCreatin entity.setDate(LocalDate.fromDaysSinceEpoch(1)); operations.insert(entity); - AllPossibleTypes loaded = operations.selectOneById(entity.getId(), AllPossibleTypes.class); + AllPossibleTypes loaded = load(entity); assertThat(loaded.getDate()).isEqualTo(entity.getDate()); } @@ -287,7 +287,7 @@ public class CassandraTypeMappingIntegrationTest extends AbstractKeyspaceCreatin entity.setBigInteger(new BigInteger("123456")); operations.insert(entity); - AllPossibleTypes loaded = operations.selectOneById(entity.getId(), AllPossibleTypes.class); + AllPossibleTypes loaded = load(entity); assertThat(loaded.getBigInteger()).isEqualTo(entity.getBigInteger()); } @@ -299,7 +299,7 @@ public class CassandraTypeMappingIntegrationTest extends AbstractKeyspaceCreatin entity.setBigDecimal(new BigDecimal("123456.7890123")); operations.insert(entity); - AllPossibleTypes loaded = operations.selectOneById(entity.getId(), AllPossibleTypes.class); + AllPossibleTypes loaded = load(entity); assertThat(loaded.getBigDecimal()).isEqualTo(entity.getBigDecimal()); } @@ -311,7 +311,7 @@ public class CassandraTypeMappingIntegrationTest extends AbstractKeyspaceCreatin entity.setBlob(ByteBuffer.wrap("Hello".getBytes())); operations.insert(entity); - AllPossibleTypes loaded = operations.selectOneById(entity.getId(), AllPossibleTypes.class); + AllPossibleTypes loaded = load(entity); ByteBuffer blob = loaded.getBlob(); byte[] bytes = new byte[blob.remaining()]; @@ -326,7 +326,7 @@ public class CassandraTypeMappingIntegrationTest extends AbstractKeyspaceCreatin entity.setSetOfString(Collections.singleton("hello")); operations.insert(entity); - AllPossibleTypes loaded = operations.selectOneById(entity.getId(), AllPossibleTypes.class); + AllPossibleTypes loaded = load(entity); assertThat(loaded.getSetOfString()).isEqualTo(entity.getSetOfString()); } @@ -338,7 +338,7 @@ public class CassandraTypeMappingIntegrationTest extends AbstractKeyspaceCreatin entity.setSetOfString(new HashSet()); operations.insert(entity); - AllPossibleTypes loaded = operations.selectOneById(entity.getId(), AllPossibleTypes.class); + AllPossibleTypes loaded = load(entity); assertThat(loaded.getSetOfString()).isNull(); } @@ -350,7 +350,7 @@ public class CassandraTypeMappingIntegrationTest extends AbstractKeyspaceCreatin entity.setListOfString(Collections.singletonList("hello")); operations.insert(entity); - AllPossibleTypes loaded = operations.selectOneById(entity.getId(), AllPossibleTypes.class); + AllPossibleTypes loaded = load(entity); assertThat(loaded.getListOfString()).isEqualTo(entity.getListOfString()); } @@ -362,7 +362,7 @@ public class CassandraTypeMappingIntegrationTest extends AbstractKeyspaceCreatin entity.setListOfString(new ArrayList()); operations.insert(entity); - AllPossibleTypes loaded = operations.selectOneById(entity.getId(), AllPossibleTypes.class); + AllPossibleTypes loaded = load(entity); assertThat(loaded.getListOfString()).isNull(); } @@ -374,7 +374,7 @@ public class CassandraTypeMappingIntegrationTest extends AbstractKeyspaceCreatin entity.setMapOfString(Collections.singletonMap("hello", "world")); operations.insert(entity); - AllPossibleTypes loaded = operations.selectOneById(entity.getId(), AllPossibleTypes.class); + AllPossibleTypes loaded = load(entity); assertThat(loaded.getMapOfString()).isEqualTo(entity.getMapOfString()); } @@ -386,7 +386,7 @@ public class CassandraTypeMappingIntegrationTest extends AbstractKeyspaceCreatin entity.setMapOfString(new HashMap()); operations.insert(entity); - AllPossibleTypes loaded = operations.selectOneById(entity.getId(), AllPossibleTypes.class); + AllPossibleTypes loaded = load(entity); assertThat(loaded.getMapOfString()).isNull(); } @@ -398,7 +398,7 @@ public class CassandraTypeMappingIntegrationTest extends AbstractKeyspaceCreatin entity.setAnEnum(Condition.MINT); operations.insert(entity); - AllPossibleTypes loaded = operations.selectOneById(entity.getId(), AllPossibleTypes.class); + AllPossibleTypes loaded = load(entity); Assertions.assertThat(loaded.getAnEnum()).isEqualTo(entity.getAnEnum()); } @@ -450,7 +450,7 @@ public class CassandraTypeMappingIntegrationTest extends AbstractKeyspaceCreatin entity.setLocalDate(java.time.LocalDate.of(2010, 7, 4)); operations.insert(entity); - AllPossibleTypes loaded = operations.selectOneById(entity.getId(), AllPossibleTypes.class); + AllPossibleTypes loaded = load(entity); assertThat(loaded.getLocalDate()).isEqualTo(entity.getLocalDate()); } @@ -462,7 +462,7 @@ public class CassandraTypeMappingIntegrationTest extends AbstractKeyspaceCreatin entity.setLocalDateTime(java.time.LocalDateTime.of(2010, 7, 4, 1, 2, 3)); operations.insert(entity); - AllPossibleTypes loaded = operations.selectOneById(entity.getId(), AllPossibleTypes.class); + AllPossibleTypes loaded = load(entity); assertThat(loaded.getLocalDateTime()).isEqualTo(entity.getLocalDateTime()); } @@ -474,7 +474,7 @@ public class CassandraTypeMappingIntegrationTest extends AbstractKeyspaceCreatin entity.setLocalTime(java.time.LocalTime.of(1, 2, 3)); operations.insert(entity); - AllPossibleTypes loaded = operations.selectOneById(entity.getId(), AllPossibleTypes.class); + AllPossibleTypes loaded = load(entity); assertThat(loaded.getLocalTime()).isEqualTo(entity.getLocalTime()); } @@ -486,7 +486,7 @@ public class CassandraTypeMappingIntegrationTest extends AbstractKeyspaceCreatin entity.setInstant(java.time.Instant.now()); operations.insert(entity); - AllPossibleTypes loaded = operations.selectOneById(entity.getId(), AllPossibleTypes.class); + AllPossibleTypes loaded = load(entity); assertThat(loaded.getInstant()).isEqualTo(entity.getInstant()); } @@ -498,7 +498,7 @@ public class CassandraTypeMappingIntegrationTest extends AbstractKeyspaceCreatin entity.setZoneId(java.time.ZoneId.of("Europe/Paris")); operations.insert(entity); - AllPossibleTypes loaded = operations.selectOneById(entity.getId(), AllPossibleTypes.class); + AllPossibleTypes loaded = load(entity); assertThat(loaded.getZoneId()).isEqualTo(entity.getZoneId()); } @@ -510,7 +510,7 @@ public class CassandraTypeMappingIntegrationTest extends AbstractKeyspaceCreatin entity.setJodaLocalDate(new org.joda.time.LocalDate(2010, 7, 4)); operations.insert(entity); - AllPossibleTypes loaded = operations.selectOneById(entity.getId(), AllPossibleTypes.class); + AllPossibleTypes loaded = load(entity); assertThat(loaded.getJodaLocalDate()).isEqualTo(entity.getJodaLocalDate()); } @@ -522,7 +522,7 @@ public class CassandraTypeMappingIntegrationTest extends AbstractKeyspaceCreatin entity.setJodaDateMidnight(new org.joda.time.DateMidnight(2010, 7, 4)); operations.insert(entity); - AllPossibleTypes loaded = operations.selectOneById(entity.getId(), AllPossibleTypes.class); + AllPossibleTypes loaded = load(entity); assertThat(loaded.getJodaDateMidnight()).isEqualTo(entity.getJodaDateMidnight()); } @@ -534,7 +534,7 @@ public class CassandraTypeMappingIntegrationTest extends AbstractKeyspaceCreatin entity.setJodaDateTime(new org.joda.time.DateTime(2010, 7, 4, 1, 2, 3)); operations.insert(entity); - AllPossibleTypes loaded = operations.selectOneById(entity.getId(), AllPossibleTypes.class); + AllPossibleTypes loaded = load(entity); assertThat(loaded.getJodaDateTime()).isEqualTo(entity.getJodaDateTime()); } @@ -546,7 +546,7 @@ public class CassandraTypeMappingIntegrationTest extends AbstractKeyspaceCreatin entity.setBpLocalDate(org.threeten.bp.LocalDate.of(2010, 7, 4)); operations.insert(entity); - AllPossibleTypes loaded = operations.selectOneById(entity.getId(), AllPossibleTypes.class); + AllPossibleTypes loaded = load(entity); assertThat(loaded.getBpLocalDate()).isEqualTo(entity.getBpLocalDate()); } @@ -558,7 +558,7 @@ public class CassandraTypeMappingIntegrationTest extends AbstractKeyspaceCreatin entity.setBpLocalDateTime(org.threeten.bp.LocalDateTime.of(2010, 7, 4, 1, 2, 3)); operations.insert(entity); - AllPossibleTypes loaded = operations.selectOneById(entity.getId(), AllPossibleTypes.class); + AllPossibleTypes loaded = load(entity); assertThat(loaded.getBpLocalDateTime()).isEqualTo(entity.getBpLocalDateTime()); } @@ -570,7 +570,7 @@ public class CassandraTypeMappingIntegrationTest extends AbstractKeyspaceCreatin entity.setBpLocalTime(org.threeten.bp.LocalTime.of(1, 2, 3)); operations.insert(entity); - AllPossibleTypes loaded = operations.selectOneById(entity.getId(), AllPossibleTypes.class); + AllPossibleTypes loaded = load(entity); assertThat(loaded.getBpLocalTime()).isEqualTo(entity.getBpLocalTime()); } @@ -582,7 +582,7 @@ public class CassandraTypeMappingIntegrationTest extends AbstractKeyspaceCreatin entity.setBpInstant(org.threeten.bp.Instant.now()); operations.insert(entity); - AllPossibleTypes loaded = operations.selectOneById(entity.getId(), AllPossibleTypes.class); + AllPossibleTypes loaded = load(entity); assertThat(loaded.getBpZoneId()).isEqualTo(entity.getBpZoneId()); } @@ -594,7 +594,7 @@ public class CassandraTypeMappingIntegrationTest extends AbstractKeyspaceCreatin entity.setBpZoneId(org.threeten.bp.ZoneId.of("Europe/Paris")); operations.insert(entity); - AllPossibleTypes loaded = operations.selectOneById(entity.getId(), AllPossibleTypes.class); + AllPossibleTypes loaded = load(entity); assertThat(loaded.getBpZoneId()).isEqualTo(entity.getBpZoneId()); } @@ -612,6 +612,10 @@ public class CassandraTypeMappingIntegrationTest extends AbstractKeyspaceCreatin assertThat(loaded.getCount()).isEqualTo(entity.getCount()); } + private AllPossibleTypes load(AllPossibleTypes entity) { + return operations.selectOneById(entity.getId(), AllPossibleTypes.class); + } + public enum Condition { MINT; } diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/convert/CustomConversionIntegrationTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/convert/CustomConversionIntegrationTests.java index 435f071f5..9a65cb911 100755 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/convert/CustomConversionIntegrationTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/convert/CustomConversionIntegrationTests.java @@ -175,8 +175,7 @@ public class CustomConversionIntegrationTests extends AbstractKeyspaceCreatingIn assertThat(employee.getId()).isEqualTo("employee-id"); assertThat(employee.getPeople()).isNotNull(); - Person apu = employee.getPeople().iterator().next(); - assertThat(apu.getFirstname()).isEqualTo("Apu"); + assertThat(employee.getPeople()).extracting(Person::getFirstname).contains("Apu"); } @Test // DATACASS-296 diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/convert/MappingCassandraConverterUDTIntegrationTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/convert/MappingCassandraConverterUDTIntegrationTests.java index ca353f554..c0ae88419 100644 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/convert/MappingCassandraConverterUDTIntegrationTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/convert/MappingCassandraConverterUDTIntegrationTests.java @@ -215,7 +215,7 @@ public class MappingCassandraConverterUDTIntegrationTests extends AbstractSpring public void shouldWriteUdt() { CassandraPersistentEntity persistentEntity = converter.getMappingContext() - .getPersistentEntity(AddressUserType.class); + .getRequiredPersistentEntity(AddressUserType.class); UDTValue udtValue = persistentEntity.getUserType().newValue(); udtValue.setString("zip", "69469"); udtValue.setString("city", "Weinheim"); @@ -254,7 +254,7 @@ public class MappingCassandraConverterUDTIntegrationTests extends AbstractSpring public void shouldWriteMappedUdtPk() { CassandraPersistentEntity persistentEntity = converter.getMappingContext() - .getPersistentEntity(AddressUserType.class); + .getRequiredPersistentEntity(AddressUserType.class); UDTValue udtValue = persistentEntity.getUserType().newValue(); udtValue.setString("zip", "69469"); udtValue.setString("city", "Weinheim"); diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/convert/MappingCassandraConverterUnitTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/convert/MappingCassandraConverterUnitTests.java index e9bb49045..e73eeaad5 100755 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/convert/MappingCassandraConverterUnitTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/convert/MappingCassandraConverterUnitTests.java @@ -674,7 +674,7 @@ public class MappingCassandraConverterUnitTests { Delete delete = QueryBuilder.delete().from("table"); - mappingCassandraConverter.write("42", delete.where(), mappingContext.getPersistentEntity(Person.class)); + mappingCassandraConverter.write("42", delete.where(), mappingContext.getRequiredPersistentEntity(Person.class)); assertThat(getWherePredicates(delete)).containsEntry("id", "42"); } @@ -687,7 +687,7 @@ public class MappingCassandraConverterUnitTests { Person person = new Person(); person.setId("42"); - mappingCassandraConverter.write(person, delete.where(), mappingContext.getPersistentEntity(Person.class)); + mappingCassandraConverter.write(person, delete.where(), mappingContext.getRequiredPersistentEntity(Person.class)); assertThat(getWherePredicates(delete)).containsEntry("id", "42"); } @@ -697,7 +697,8 @@ public class MappingCassandraConverterUnitTests { Delete delete = QueryBuilder.delete().from("table"); - mappingCassandraConverter.write(new Person(), delete.where(), mappingContext.getPersistentEntity(Person.class)); + mappingCassandraConverter.write(new Person(), delete.where(), + mappingContext.getRequiredPersistentEntity(Person.class)); } @Test // DATACASS-308 @@ -705,7 +706,8 @@ public class MappingCassandraConverterUnitTests { Delete delete = QueryBuilder.delete().from("table"); - mappingCassandraConverter.write(id("id", "42"), delete.where(), mappingContext.getPersistentEntity(Person.class)); + mappingCassandraConverter.write(id("id", "42"), delete.where(), + mappingContext.getRequiredPersistentEntity(Person.class)); assertThat(getWherePredicates(delete)).containsEntry("id", "42"); } @@ -720,7 +722,7 @@ public class MappingCassandraConverterUnitTests { entity.setLastname("White"); mappingCassandraConverter.write(entity, delete.where(), - mappingContext.getPersistentEntity(TypeWithCompositeKey.class)); + mappingContext.getRequiredPersistentEntity(TypeWithCompositeKey.class)); assertThat(getWherePredicates(delete)).containsEntry("firstname", "Walter"); assertThat(getWherePredicates(delete)).containsEntry("lastname", "White"); @@ -732,7 +734,7 @@ public class MappingCassandraConverterUnitTests { Delete delete = QueryBuilder.delete().from("table"); mappingCassandraConverter.write(id("firstname", "Walter").with("lastname", "White"), delete.where(), - mappingContext.getPersistentEntity(TypeWithCompositeKey.class)); + mappingContext.getRequiredPersistentEntity(TypeWithCompositeKey.class)); assertThat(getWherePredicates(delete)).containsEntry("firstname", "Walter"); assertThat(getWherePredicates(delete)).containsEntry("lastname", "White"); @@ -747,7 +749,8 @@ public class MappingCassandraConverterUnitTests { entity.setFirstname("Walter"); entity.setLastname("White"); - mappingCassandraConverter.write(entity, delete.where(), mappingContext.getPersistentEntity(TypeWithMapId.class)); + mappingCassandraConverter.write(entity, delete.where(), + mappingContext.getRequiredPersistentEntity(TypeWithMapId.class)); assertThat(getWherePredicates(delete)).containsEntry("firstname", "Walter"); assertThat(getWherePredicates(delete)).containsEntry("lastname", "White"); @@ -759,7 +762,7 @@ public class MappingCassandraConverterUnitTests { Delete delete = QueryBuilder.delete().from("table"); mappingCassandraConverter.write(Condition.MINT, delete.where(), - mappingContext.getPersistentEntity(EnumPrimaryKey.class)); + mappingContext.getRequiredPersistentEntity(EnumPrimaryKey.class)); assertThat(getWherePredicates(delete)).containsEntry("condition", "MINT"); } @@ -770,7 +773,7 @@ public class MappingCassandraConverterUnitTests { Delete delete = QueryBuilder.delete().from("table"); mappingCassandraConverter.write(id("firstname", "Walter").with("lastname", "White"), delete.where(), - mappingContext.getPersistentEntity(TypeWithMapId.class)); + mappingContext.getRequiredPersistentEntity(TypeWithMapId.class)); assertThat(getWherePredicates(delete)).containsEntry("firstname", "Walter"); assertThat(getWherePredicates(delete)).containsEntry("lastname", "White"); @@ -788,7 +791,8 @@ public class MappingCassandraConverterUnitTests { TypeWithKeyClass entity = new TypeWithKeyClass(); entity.setKey(key); - mappingCassandraConverter.write(entity, delete.where(), mappingContext.getPersistentEntity(TypeWithKeyClass.class)); + mappingCassandraConverter.write(entity, delete.where(), + mappingContext.getRequiredPersistentEntity(TypeWithKeyClass.class)); assertThat(getWherePredicates(delete)).containsEntry("firstname", "Walter"); assertThat(getWherePredicates(delete)).containsEntry("lastname", "White"); @@ -800,7 +804,7 @@ public class MappingCassandraConverterUnitTests { Delete delete = QueryBuilder.delete().from("table"); mappingCassandraConverter.write(new TypeWithKeyClass(), delete.where(), - mappingContext.getPersistentEntity(TypeWithKeyClass.class)); + mappingContext.getRequiredPersistentEntity(TypeWithKeyClass.class)); } @Test // DATACASS-308 @@ -812,7 +816,8 @@ public class MappingCassandraConverterUnitTests { key.setFirstname("Walter"); key.setLastname("White"); - mappingCassandraConverter.write(key, delete.where(), mappingContext.getPersistentEntity(TypeWithKeyClass.class)); + mappingCassandraConverter.write(key, delete.where(), + mappingContext.getRequiredPersistentEntity(TypeWithKeyClass.class)); assertThat(getWherePredicates(delete)).containsEntry("firstname", "Walter"); assertThat(getWherePredicates(delete)).containsEntry("lastname", "White"); @@ -824,7 +829,7 @@ public class MappingCassandraConverterUnitTests { Delete delete = QueryBuilder.delete().from("table"); mappingCassandraConverter.write(id("firstname", "Walter").with("lastname", "White"), delete.where(), - mappingContext.getPersistentEntity(TypeWithKeyClass.class)); + mappingContext.getRequiredPersistentEntity(TypeWithKeyClass.class)); assertThat(getWherePredicates(delete)).containsEntry("firstname", "Walter"); assertThat(getWherePredicates(delete)).containsEntry("lastname", "White"); @@ -836,7 +841,7 @@ public class MappingCassandraConverterUnitTests { Delete delete = QueryBuilder.delete().from("table"); mappingCassandraConverter.write(id("unknown", "Walter"), delete.where(), - mappingContext.getPersistentEntity(TypeWithMapId.class)); + mappingContext.getRequiredPersistentEntity(TypeWithMapId.class)); } @SuppressWarnings("unchecked") 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 62741c379..aefb8b241 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 @@ -30,7 +30,7 @@ import org.springframework.util.concurrent.ListenableFuture; /** * Integration tests for {@link AsyncCassandraTemplate}. - * + * * @author Mark Paluch */ public class AsyncCassandraTemplateIntegrationTests extends AbstractKeyspaceCreatingIntegrationTest { @@ -57,7 +57,7 @@ public class AsyncCassandraTemplateIntegrationTests extends AbstractKeyspaceCrea ListenableFuture insert = template.insert(person); - assertThat(getUninterruptibly(insert)).isNotNull().isEqualTo(person); + assertThat(getUninterruptibly(insert)).isEqualTo(person); assertThat(getUninterruptibly(template.selectOneById(person.getId(), Person.class))).isEqualTo(person); } @@ -66,7 +66,7 @@ public class AsyncCassandraTemplateIntegrationTests extends AbstractKeyspaceCrea Person person = new Person("heisenberg", "Walter", "White"); - template.insert(person).get(); + getUninterruptibly(template.insert(person)); ListenableFuture count = template.count(Person.class); assertThat(getUninterruptibly(count)).isEqualTo(1L); @@ -76,12 +76,12 @@ public class AsyncCassandraTemplateIntegrationTests extends AbstractKeyspaceCrea public void updateShouldUpdateEntity() throws Exception { Person person = new Person("heisenberg", "Walter", "White"); - template.insert(person).get(); + getUninterruptibly(template.insert(person)); person.setFirstname("Walter Hartwell"); - Person updated = template.update(person).get(); - assertThat(updated).isNotNull(); + Person updated = getUninterruptibly(template.update(person)); + assertThat(updated).isNotNull(); assertThat(getUninterruptibly(template.selectOneById(person.getId(), Person.class))).isEqualTo(person); } @@ -89,11 +89,11 @@ public class AsyncCassandraTemplateIntegrationTests extends AbstractKeyspaceCrea public void deleteShouldRemoveEntity() throws Exception { Person person = new Person("heisenberg", "Walter", "White"); - template.insert(person).get(); + getUninterruptibly(template.insert(person)); + + Person deleted = getUninterruptibly(template.delete(person)); - Person deleted = template.delete(person).get(); assertThat(deleted).isNotNull(); - assertThat(getUninterruptibly(template.selectOneById(person.getId(), Person.class))).isNull(); } @@ -101,9 +101,9 @@ public class AsyncCassandraTemplateIntegrationTests extends AbstractKeyspaceCrea public void deleteByIdShouldRemoveEntity() throws Exception { Person person = new Person("heisenberg", "Walter", "White"); - template.insert(person).get(); + getUninterruptibly(template.insert(person)); - Boolean deleted = template.deleteById(person.getId(), Person.class).get(); + Boolean deleted = getUninterruptibly(template.deleteById(person.getId(), Person.class)); assertThat(deleted).isTrue(); assertThat(getUninterruptibly(template.selectOneById(person.getId(), Person.class))).isNull(); diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/AsyncCassandraTemplateUnitTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/AsyncCassandraTemplateUnitTests.java index 91113045b..a9b8b2c6c 100644 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/AsyncCassandraTemplateUnitTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/AsyncCassandraTemplateUnitTests.java @@ -157,7 +157,8 @@ public class AsyncCassandraTemplateUnitTests { when(row.getObject(1)).thenReturn("Walter"); when(row.getObject(2)).thenReturn("White"); - ListenableFuture future = template.selectOne("SELECT * FROM person WHERE id='myid';", Person.class); + ListenableFuture future = template.selectOne("SELECT * FROM person WHERE id='myid';", + Person.class); assertThat(getUninterruptibly(future)).isEqualTo(new Person("myid", "Walter", "White")); verify(session).executeAsync(statementCaptor.capture()); 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 cf46c315e..de044fdd3 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 @@ -69,7 +69,7 @@ public class CassandraTemplateIntegrationTests extends AbstractKeyspaceCreatingI Person inserted = template.insert(person); - assertThat(inserted).isNotNull().isEqualTo(person); + assertThat(inserted).isEqualTo(person); assertThat(template.selectOneById(person.getId(), Person.class)).isEqualTo(person); } @@ -91,9 +91,10 @@ public class CassandraTemplateIntegrationTests extends AbstractKeyspaceCreatingI template.insert(person); person.setFirstname("Walter Hartwell"); - Person updated = template.update(person); - assertThat(updated).isNotNull(); + Person updated = template.update(person); + + assertThat(updated).isNotNull(); assertThat(template.selectOneById(person.getId(), Person.class)).isEqualTo(person); } @@ -104,8 +105,8 @@ public class CassandraTemplateIntegrationTests extends AbstractKeyspaceCreatingI template.insert(person); Person deleted = template.delete(person); - assertThat(deleted).isNotNull(); + assertThat(deleted).isNotNull(); assertThat(template.selectOneById(person.getId(), Person.class)).isNull(); } @@ -202,7 +203,6 @@ public class CassandraTemplateIntegrationTests extends AbstractKeyspaceCreatingI UserToken loaded = template.selectOneById( BasicMapId.id("userId", userToken.getUserId()).with("token", userToken.getToken()), UserToken.class); - assertThat(loaded).isNotNull(); assertThat(loaded.getUserComment()).isEqualTo("comment"); template.delete(userToken); 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 cc770128a..40767c396 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 @@ -49,7 +49,7 @@ import com.datastax.driver.core.querybuilder.Batch; /** * Unit tests for {@link CassandraTemplate}. - * + * * @author Mark Paluch */ @RunWith(MockitoJUnitRunner.class) diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/mapping/BasicCassandraMappingContextUnitTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/mapping/BasicCassandraMappingContextUnitTests.java index 342d1fdef..e26f1594b 100755 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/mapping/BasicCassandraMappingContextUnitTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/mapping/BasicCassandraMappingContextUnitTests.java @@ -23,6 +23,7 @@ import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.Optional; import org.junit.Before; import org.junit.Test; @@ -56,18 +57,12 @@ public class BasicCassandraMappingContextUnitTests { @Before public void before() { - mappingContext.setUserTypeResolver(new UserTypeResolver() { - - @Override - public UserType resolveType(CqlIdentifier typeName) { - return null; - } - }); + mappingContext.setUserTypeResolver(typeName -> null); } @Test - public void testGetPersistentEntityOfTransientType() { - mappingContext.getPersistentEntity(Transient.class); + public void testgetRequiredPersistentEntityOfTransientType() { + mappingContext.getRequiredPersistentEntity(Transient.class); } private static class Transient {} @@ -75,7 +70,7 @@ public class BasicCassandraMappingContextUnitTests { @Test public void testGetExistingPersistentEntityHappyPath() { - mappingContext.getPersistentEntity(X.class); + mappingContext.getRequiredPersistentEntity(X.class); assertThat(mappingContext.contains(X.class)).isTrue(); assertThat(mappingContext.getExistingPersistentEntity(X.class)).isNotNull(); @@ -85,16 +80,20 @@ public class BasicCassandraMappingContextUnitTests { @Test // DATACASS-248 public void primaryKeyOnPropertyShouldWork() { - CassandraPersistentEntity persistentEntity = mappingContext.getPersistentEntity(PrimaryKeyOnProperty.class); + CassandraPersistentEntity persistentEntity = mappingContext + .getRequiredPersistentEntity(PrimaryKeyOnProperty.class); - CassandraPersistentProperty idProperty = persistentEntity.getIdProperty(); + Optional idProperty = persistentEntity.getIdProperty(); - assertThat(idProperty.getColumnName().toCql()).isEqualTo("foo"); + assertThat(idProperty).hasValueSatisfying(actual -> { - List columnNames = idProperty.getColumnNames(); + assertThat(actual.getColumnName().toCql()).isEqualTo("foo"); - assertThat(columnNames).hasSize(1); - assertThat(columnNames.get(0).toCql()).isEqualTo("foo"); + List columnNames = actual.getColumnNames(); + + assertThat(columnNames).hasSize(1); + assertThat(columnNames.get(0).toCql()).isEqualTo("foo"); + }); } @Table @@ -116,18 +115,18 @@ public class BasicCassandraMappingContextUnitTests { public void primaryKeyColumnsOnPropertyShouldWork() { CassandraPersistentEntity persistentEntity = mappingContext - .getPersistentEntity(PrimaryKeyColumnsOnProperty.class); + .getRequiredPersistentEntity(PrimaryKeyColumnsOnProperty.class); assertThat(persistentEntity.isCompositePrimaryKey()).isFalse(); - CassandraPersistentProperty firstname = persistentEntity.getPersistentProperty("firstname"); + CassandraPersistentProperty firstname = persistentEntity.getRequiredPersistentProperty("firstname"); assertThat(firstname.isCompositePrimaryKey()).isFalse(); assertThat(firstname.isPrimaryKeyColumn()).isTrue(); assertThat(firstname.isPartitionKeyColumn()).isTrue(); assertThat(firstname.getColumnName().toCql()).isEqualTo("firstname"); - CassandraPersistentProperty lastname = persistentEntity.getPersistentProperty("lastname"); + CassandraPersistentProperty lastname = persistentEntity.getRequiredPersistentProperty("lastname"); assertThat(lastname.isPrimaryKeyColumn()).isTrue(); assertThat(lastname.isClusterKeyColumn()).isTrue(); @@ -163,25 +162,27 @@ public class BasicCassandraMappingContextUnitTests { public void primaryKeyClassWithPrimaryKeyColumnsOnPropertyShouldWork() { CassandraPersistentEntity persistentEntity = mappingContext - .getPersistentEntity(PrimaryKeyOnPropertyWithPrimaryKeyClass.class); + .getRequiredPersistentEntity(PrimaryKeyOnPropertyWithPrimaryKeyClass.class); CassandraPersistentEntity primaryKeyClass = mappingContext - .getPersistentEntity(CompositePrimaryKeyClassWithProperties.class); + .getRequiredPersistentEntity(CompositePrimaryKeyClassWithProperties.class); assertThat(persistentEntity.isCompositePrimaryKey()).isFalse(); - assertThat(persistentEntity.getPersistentProperty("key").isCompositePrimaryKey()).isTrue(); + assertThat( + persistentEntity.getPersistentProperty("key").map(CassandraPersistentProperty::isCompositePrimaryKey).get()) + .isTrue(); assertThat(primaryKeyClass.isCompositePrimaryKey()).isTrue(); assertThat(primaryKeyClass.getCompositePrimaryKeyProperties()).hasSize(2); - CassandraPersistentProperty firstname = primaryKeyClass.getPersistentProperty("firstname"); + CassandraPersistentProperty firstname = primaryKeyClass.getRequiredPersistentProperty("firstname"); assertThat(firstname.isPrimaryKeyColumn()).isTrue(); assertThat(firstname.isPartitionKeyColumn()).isTrue(); assertThat(firstname.isClusterKeyColumn()).isFalse(); assertThat(firstname.getColumnName().toCql()).isEqualTo("firstname"); - CassandraPersistentProperty lastname = primaryKeyClass.getPersistentProperty("lastname"); + CassandraPersistentProperty lastname = primaryKeyClass.getRequiredPersistentProperty("lastname"); assertThat(lastname.isPrimaryKeyColumn()).isTrue(); assertThat(lastname.isPartitionKeyColumn()).isFalse(); @@ -193,7 +194,7 @@ public class BasicCassandraMappingContextUnitTests { public void createdTableSpecificationShouldConsiderClusterColumnOrdering() { CassandraPersistentEntity persistentEntity = mappingContext - .getPersistentEntity(EntityWithOrderedClusteredColumns.class); + .getRequiredPersistentEntity(EntityWithOrderedClusteredColumns.class); CreateTableSpecification tableSpecification = mappingContext.getCreateTableSpecificationFor(persistentEntity); @@ -217,7 +218,7 @@ public class BasicCassandraMappingContextUnitTests { public void createdTableSpecificationShouldConsiderPrimaryKeyClassClusterColumnOrdering() { CassandraPersistentEntity persistentEntity = mappingContext - .getPersistentEntity(EntityWithPrimaryKeyWithOrderedClusteredColumns.class); + .getRequiredPersistentEntity(EntityWithPrimaryKeyWithOrderedClusteredColumns.class); CreateTableSpecification tableSpecification = mappingContext.getCreateTableSpecificationFor(persistentEntity); @@ -324,12 +325,12 @@ public class BasicCassandraMappingContextUnitTests { .setCustomConversions(new CustomConversions(Collections.singletonList(StringMapToStringConverter.INSTANCE))); CassandraPersistentEntity persistentEntity = mappingContext - .getPersistentEntity(TypeWithCustomConvertedMap.class); + .getRequiredPersistentEntity(TypeWithCustomConvertedMap.class); - assertThat(mappingContext.getDataType(persistentEntity.getPersistentProperty("stringMap"))) + assertThat(mappingContext.getDataType(persistentEntity.getRequiredPersistentProperty("stringMap"))) .isEqualTo(DataType.varchar()); - assertThat(mappingContext.getDataType(persistentEntity.getPersistentProperty("blobMap"))) + assertThat(mappingContext.getDataType(persistentEntity.getRequiredPersistentProperty("blobMap"))) .isEqualTo(DataType.ascii()); } @@ -339,16 +340,17 @@ public class BasicCassandraMappingContextUnitTests { mappingContext .setCustomConversions(new CustomConversions(Collections.singletonList(HumanToStringConverter.INSTANCE))); - CassandraPersistentEntity persistentEntity = mappingContext.getPersistentEntity(TypeWithListOfHumans.class); + CassandraPersistentEntity persistentEntity = mappingContext + .getRequiredPersistentEntity(TypeWithListOfHumans.class); - assertThat(mappingContext.getDataType(persistentEntity.getPersistentProperty("humans"))) + assertThat(mappingContext.getDataType(persistentEntity.getRequiredPersistentProperty("humans"))) .isEqualTo(DataType.list(DataType.varchar())); } @Test // DATACASS-172 public void shouldRegisterUdtTypes() { - CassandraPersistentEntity persistentEntity = mappingContext.getPersistentEntity(MappedUdt.class); + CassandraPersistentEntity persistentEntity = mappingContext.getRequiredPersistentEntity(MappedUdt.class); assertThat(persistentEntity.isUserDefinedType()).isTrue(); } @@ -356,7 +358,7 @@ public class BasicCassandraMappingContextUnitTests { @Test // DATACASS-172 public void getNonPrimaryKeyEntitiesShouldNotContainUdt() { - CassandraPersistentEntity existingPersistentEntity = mappingContext.getPersistentEntity(MappedUdt.class); + CassandraPersistentEntity existingPersistentEntity = mappingContext.getRequiredPersistentEntity(MappedUdt.class); assertThat(mappingContext.getTableEntities()).doesNotContain(existingPersistentEntity); } @@ -364,7 +366,7 @@ public class BasicCassandraMappingContextUnitTests { @Test // DATACASS-172, DATACASS-359 public void getPersistentEntitiesShouldContainUdt() { - CassandraPersistentEntity existingPersistentEntity = mappingContext.getPersistentEntity(MappedUdt.class); + CassandraPersistentEntity existingPersistentEntity = mappingContext.getRequiredPersistentEntity(MappedUdt.class); assertThat(mappingContext.getPersistentEntities(true)).contains(existingPersistentEntity); assertThat(mappingContext.getUserDefinedTypeEntities()).contains(existingPersistentEntity); @@ -395,7 +397,7 @@ public class BasicCassandraMappingContextUnitTests { } }); - mappingContext.getPersistentEntity(WithUdt.class); + mappingContext.getRequiredPersistentEntity(WithUdt.class); assertThat(mappingContext.usesUserType(myTypeMock)).isTrue(); } @@ -414,7 +416,7 @@ public class BasicCassandraMappingContextUnitTests { } }); - mappingContext.getPersistentEntity(MappedUdt.class); + mappingContext.getRequiredPersistentEntity(MappedUdt.class); assertThat(mappingContext.usesUserType(myTypeMock)).isTrue(); } @@ -423,15 +425,16 @@ public class BasicCassandraMappingContextUnitTests { public void createTableForComplexPrimaryKeyShouldFail() { try { - mappingContext - .getCreateTableSpecificationFor(mappingContext.getPersistentEntity(EntityWithComplexPrimaryKeyColumn.class)); + mappingContext.getCreateTableSpecificationFor( + mappingContext.getRequiredPersistentEntity(EntityWithComplexPrimaryKeyColumn.class)); fail("Missing InvalidDataAccessApiUsageException"); } catch (InvalidDataAccessApiUsageException e) { assertThat(e).hasMessageContaining("Unknown type [class java.lang.Object] for property [complexObject]"); } try { - mappingContext.getCreateTableSpecificationFor(mappingContext.getPersistentEntity(EntityWithComplexId.class)); + mappingContext + .getCreateTableSpecificationFor(mappingContext.getRequiredPersistentEntity(EntityWithComplexId.class)); fail("Missing InvalidDataAccessApiUsageException"); } catch (InvalidDataAccessApiUsageException e) { assertThat(e).hasMessageContaining("Unknown type [class java.lang.Object] for property [complexObject]"); @@ -439,7 +442,7 @@ public class BasicCassandraMappingContextUnitTests { try { mappingContext.getCreateTableSpecificationFor( - mappingContext.getPersistentEntity(EntityWithPrimaryKeyClassWithComplexId.class)); + mappingContext.getRequiredPersistentEntity(EntityWithPrimaryKeyClassWithComplexId.class)); fail("Missing InvalidDataAccessApiUsageException"); } catch (InvalidDataAccessApiUsageException e) { assertThat(e).hasMessageContaining("Unknown type [class java.lang.Object] for property [complexObject]"); diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/mapping/BasicCassandraPersistentEntityMetadataVerifierUnitTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/mapping/BasicCassandraPersistentEntityMetadataVerifierUnitTests.java index 37e70be65..24d7fc5e1 100755 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/mapping/BasicCassandraPersistentEntityMetadataVerifierUnitTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/mapping/BasicCassandraPersistentEntityMetadataVerifierUnitTests.java @@ -43,29 +43,29 @@ public class BasicCassandraPersistentEntityMetadataVerifierUnitTests { @Test // DATACASS-258 public void shouldAllowInterfaceTypes() { - verifier.verify(getEntity(MyInterface.class)); + verifier.verify(context.getRequiredPersistentEntity(MyInterface.class)); } @Test // DATACASS-258 public void testPrimaryKeyClass() { - verifier.verify(getEntity(Animal.class)); + verifier.verify(context.getRequiredPersistentEntity(Animal.class)); } @Test // DATACASS-258 public void testNonPrimaryKeyClass() { - verifier.verify(getEntity(Person.class)); + verifier.verify(context.getRequiredPersistentEntity(Person.class)); } @Test // DATACASS-258 public void testNonPersistentType() { - verifier.verify(getEntity(NonPersistentClass.class)); + verifier.verify(context.getRequiredPersistentEntity(NonPersistentClass.class)); } @Test // DATACASS-258 public void shouldFailWithPersistentAndPrimaryKeyClassAnnotations() { try { - verifier.verify(getEntity(TooManyAnnotations.class)); + verifier.verify(context.getRequiredPersistentEntity(TooManyAnnotations.class)); fail("Missing MappingException"); } catch (MappingException e) { assertThat(e).hasMessageContaining("Entity cannot be of type @Table and @PrimaryKeyClass"); @@ -76,7 +76,7 @@ public class BasicCassandraPersistentEntityMetadataVerifierUnitTests { public void shouldFailWithoutPartitionKey() { try { - verifier.verify(getEntity(NoPartitionKey.class)); + verifier.verify(context.getRequiredPersistentEntity(NoPartitionKey.class)); fail("Missing MappingException"); } catch (MappingException e) { assertThat(e) @@ -88,7 +88,7 @@ public class BasicCassandraPersistentEntityMetadataVerifierUnitTests { public void shouldFailWithoutPrimaryKey() { try { - verifier.verify(getEntity(NoPrimaryKey.class)); + verifier.verify(context.getRequiredPersistentEntity(NoPrimaryKey.class)); fail("Missing MappingException"); } catch (MappingException e) { assertThat(e).hasMessageContaining("@Table types must have only one primary attribute, if any; Found 0"); @@ -99,17 +99,13 @@ public class BasicCassandraPersistentEntityMetadataVerifierUnitTests { public void testPkAndPkc() { try { - verifier.verify(getEntity(PrimaryKeyAndPrimaryKeyColumn.class)); + verifier.verify(context.getRequiredPersistentEntity(PrimaryKeyAndPrimaryKeyColumn.class)); fail("Missing MappingException"); } catch (MappingException e) { assertThat(e).hasMessageContaining("@Table types must not define both @Id and @PrimaryKeyColumn properties"); } } - private CassandraPersistentEntity getEntity(Class entityClass) { - return context.getPersistentEntity(entityClass); - } - interface MyInterface {} static class NonPersistentClass { diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/mapping/BasicCassandraPersistentEntityOrderPropertiesUnitTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/mapping/BasicCassandraPersistentEntityOrderPropertiesUnitTests.java index 6fa6c2054..d8085596e 100755 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/mapping/BasicCassandraPersistentEntityOrderPropertiesUnitTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/mapping/BasicCassandraPersistentEntityOrderPropertiesUnitTests.java @@ -31,6 +31,7 @@ import org.springframework.data.mapping.PropertyHandler; * Unit tests for {@link BasicCassandraMappingContext}. * * @author David Webb + * @author Mark Paluch */ public class BasicCassandraPersistentEntityOrderPropertiesUnitTests { @@ -43,12 +44,12 @@ public class BasicCassandraPersistentEntityOrderPropertiesUnitTests { @Test public void testCompositeKeyPropertyOrder() { - CassandraPersistentEntity entity = mappingContext.getPersistentEntity(CompositePK.class); + CassandraPersistentEntity entity = mappingContext.getRequiredPersistentEntity(CompositePK.class); - expected = new LinkedList(); - expected.add(entity.getPersistentProperty("key0")); - expected.add(entity.getPersistentProperty("key1")); - expected.add(entity.getPersistentProperty("key2")); + expected = new LinkedList<>(); + expected.add(entity.getRequiredPersistentProperty("key0")); + expected.add(entity.getRequiredPersistentProperty("key1")); + expected.add(entity.getRequiredPersistentProperty("key2")); final List actual = new LinkedList(); @@ -67,12 +68,12 @@ public class BasicCassandraPersistentEntityOrderPropertiesUnitTests { @Test public void testTablePropertyOrder() { - CassandraPersistentEntity entity = mappingContext.getPersistentEntity(CompositeKeyEntity.class); + CassandraPersistentEntity entity = mappingContext.getRequiredPersistentEntity(CompositeKeyEntity.class); expected = new LinkedList(); - expected.add(entity.getPersistentProperty("key")); - expected.add(entity.getPersistentProperty("attribute")); - expected.add(entity.getPersistentProperty("text")); + expected.add(entity.getRequiredPersistentProperty("key")); + expected.add(entity.getRequiredPersistentProperty("attribute")); + expected.add(entity.getRequiredPersistentProperty("text")); final List actual = new LinkedList(); diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/mapping/BasicCassandraPersistentEntityUnitTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/mapping/BasicCassandraPersistentEntityUnitTests.java index ea0b02f07..fd0aab025 100755 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/mapping/BasicCassandraPersistentEntityUnitTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/mapping/BasicCassandraPersistentEntityUnitTests.java @@ -22,6 +22,7 @@ import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +import java.util.Optional; import org.junit.Test; import org.junit.runner.RunWith; @@ -83,15 +84,15 @@ public class BasicCassandraPersistentEntityUnitTests { BasicCassandraPersistentEntity entitySpy = spy( new BasicCassandraPersistentEntity(ClassTypeInformation.from(Message.class))); - entitySpy.tableName = CqlIdentifier.cqlId("Messages", false); + entitySpy.setTableName(CqlIdentifier.cqlId("Messages", false)); - assertThat(entitySpy.forceQuote).isNull(); + assertThat(entitySpy.forceQuote).isNotPresent(); entitySpy.setForceQuote(true); - assertThat(entitySpy.forceQuote).isTrue(); + assertThat(entitySpy.forceQuote).contains(true); - verify(entitySpy, times(1)).setTableName(isA(CqlIdentifier.class)); + verify(entitySpy, times(2)).setTableName(isA(CqlIdentifier.class)); } @Test @@ -99,10 +100,10 @@ public class BasicCassandraPersistentEntityUnitTests { BasicCassandraPersistentEntity entitySpy = spy( new BasicCassandraPersistentEntity(ClassTypeInformation.from(Message.class))); - entitySpy.forceQuote = true; + entitySpy.forceQuote = Optional.of(true); entitySpy.setForceQuote(true); - assertThat(entitySpy.forceQuote).isTrue(); + assertThat(entitySpy.forceQuote).contains(true); verify(entitySpy, never()).setTableName(isA(CqlIdentifier.class)); } diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/mapping/BasicCassandraPersistentPropertyUnitTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/mapping/BasicCassandraPersistentPropertyUnitTests.java index c07390dfc..de9e6eae8 100755 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/mapping/BasicCassandraPersistentPropertyUnitTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/mapping/BasicCassandraPersistentPropertyUnitTests.java @@ -25,6 +25,7 @@ import java.util.Date; import org.junit.Test; import org.springframework.cassandra.core.cql.CqlIdentifier; import org.springframework.core.annotation.AliasFor; +import org.springframework.data.mapping.model.Property; import org.springframework.data.util.ClassTypeInformation; import org.springframework.util.ReflectionUtils; @@ -91,14 +92,14 @@ public class BasicCassandraPersistentPropertyUnitTests { "column"); assertThat(persistentProperty.getDataType().getName()).isEqualTo(Name.COUNTER); - assertThat(persistentProperty.findAnnotation(CassandraType.class)).isNotNull(); + assertThat(persistentProperty.findAnnotation(CassandraType.class)).isPresent(); } private CassandraPersistentProperty getPropertyFor(Class type, String fieldName) { Field field = ReflectionUtils.findField(type, fieldName); - return new BasicCassandraPersistentProperty(field, null, getEntity(type), new CassandraSimpleTypeHolder()); + return new BasicCassandraPersistentProperty(Property.of(field), getEntity(type), new CassandraSimpleTypeHolder()); } private BasicCassandraPersistentEntity getEntity(Class type) { diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/mapping/CassandraCompositePrimaryKeyUnitTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/mapping/CassandraCompositePrimaryKeyUnitTests.java index 454542352..d131a8897 100755 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/mapping/CassandraCompositePrimaryKeyUnitTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/mapping/CassandraCompositePrimaryKeyUnitTests.java @@ -31,6 +31,7 @@ import org.springframework.cassandra.core.PrimaryKeyType; import org.springframework.cassandra.core.cql.CqlIdentifier; import org.springframework.cassandra.core.keyspace.ColumnSpecification; import org.springframework.cassandra.core.keyspace.CreateTableSpecification; +import org.springframework.data.mapping.model.Property; import org.springframework.data.util.ClassTypeInformation; import org.springframework.util.ReflectionUtils; @@ -40,6 +41,7 @@ import com.datastax.driver.core.DataType; * Unit tests for {@link BasicCassandraPersistentProperty} with a composite primary key class. * * @author Matthew T. Adams + * @author Mark Paluch */ public class CassandraCompositePrimaryKeyUnitTests { @@ -104,15 +106,16 @@ public class CassandraCompositePrimaryKeyUnitTests { @Before public void setup() { context = new BasicCassandraMappingContext(); - thing = context.getPersistentEntity(ClassTypeInformation.from(Thing.class)); - key = context.getPersistentEntity(ClassTypeInformation.from(Key.class)); + thing = context.getRequiredPersistentEntity(ClassTypeInformation.from(Thing.class)); + key = context.getRequiredPersistentEntity(ClassTypeInformation.from(Key.class)); } @Test public void validateMappingInfo() { Field field = ReflectionUtils.findField(Thing.class, "id"); - CassandraPersistentProperty property = new BasicCassandraPersistentProperty(field, null, thing, SIMPLE_TYPE_HOLDER); + CassandraPersistentProperty property = new BasicCassandraPersistentProperty(Property.of(field), thing, + SIMPLE_TYPE_HOLDER); assertThat(property.isIdProperty()).isTrue(); assertThat(property.isCompositePrimaryKey()).isTrue(); diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/mapping/CassandraPersistentPropertyComparatorUnitTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/mapping/CassandraPersistentPropertyComparatorUnitTests.java index 0bc2d43d6..c9a8d1aa6 100755 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/mapping/CassandraPersistentPropertyComparatorUnitTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/mapping/CassandraPersistentPropertyComparatorUnitTests.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.springframework.data.cassandra.mapping; import static org.assertj.core.api.Assertions.*; @@ -31,6 +30,7 @@ import org.springframework.cassandra.core.cql.CqlIdentifier; * functionality of the {@link CassandraPersistentPropertyComparator} class. * * @author John Blum + * @author Mark Paluch * @since 1.5.0 */ @RunWith(MockitoJUnitRunner.class) @@ -177,11 +177,11 @@ public class CassandraPersistentPropertyComparatorUnitTests { public void columnNameComparisonShouldHonorContract() throws Exception { BasicCassandraMappingContext context = new BasicCassandraMappingContext(); - CassandraPersistentEntity persistentEntity = context.getPersistentEntity(TwoColumns.class); + CassandraPersistentEntity persistentEntity = context.getRequiredPersistentEntity(TwoColumns.class); - CassandraPersistentProperty annotated = persistentEntity.getPersistentProperty("annotated"); - CassandraPersistentProperty another = persistentEntity.getPersistentProperty("anotherAnnotated"); - CassandraPersistentProperty plain = persistentEntity.getPersistentProperty("plain"); + CassandraPersistentProperty annotated = persistentEntity.getRequiredPersistentProperty("annotated"); + CassandraPersistentProperty another = persistentEntity.getRequiredPersistentProperty("anotherAnnotated"); + CassandraPersistentProperty plain = persistentEntity.getRequiredPersistentProperty("plain"); assertThat(INSTANCE.compare(annotated, plain)).isLessThanOrEqualTo(-1); assertThat(INSTANCE.compare(plain, annotated)).isGreaterThanOrEqualTo(1); diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/mapping/CompositeCassandraPersistentEntityMetadataVerifierUnitTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/mapping/CompositeCassandraPersistentEntityMetadataVerifierUnitTests.java index 1ba6bd891..01914dfd5 100644 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/mapping/CompositeCassandraPersistentEntityMetadataVerifierUnitTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/mapping/CompositeCassandraPersistentEntityMetadataVerifierUnitTests.java @@ -42,39 +42,35 @@ public class CompositeCassandraPersistentEntityMetadataVerifierUnitTests { @Test // DATACASS-258 public void shouldAllowInterfaceTypes() { - verifier.verify(getEntity(MyInterface.class)); + verifier.verify(context.getRequiredPersistentEntity(MyInterface.class)); } @Test // DATACASS-258 public void testPrimaryKeyClass() { - verifier.verify(getEntity(Animal.class)); + verifier.verify(context.getRequiredPersistentEntity(Animal.class)); } @Test // DATACASS-258 public void testNonPrimaryKeyClass() { - verifier.verify(getEntity(Person.class)); + verifier.verify(context.getRequiredPersistentEntity(Person.class)); } @Test // DATACASS-258, DATACASS-359 public void shouldNotFailWithNonPersistentClasses() { - verifier.verify(getEntity(NonPersistentClass.class)); + verifier.verify(context.getRequiredPersistentEntity(NonPersistentClass.class)); } @Test // DATACASS-258 public void shouldFailWithPersistentAndPrimaryKeyClassAnnotations() { try { - verifier.verify(getEntity(TooManyAnnotations.class)); + verifier.verify(context.getRequiredPersistentEntity(TooManyAnnotations.class)); fail("Missing MappingException"); } catch (MappingException e) { assertThat(e).hasMessageContaining("Entity cannot be of type @Table and @PrimaryKeyClass"); } } - private CassandraPersistentEntity getEntity(Class entityClass) { - return context.getPersistentEntity(entityClass); - } - interface MyInterface {} static class NonPersistentClass { diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/mapping/CompoundPrimaryKeyUnitTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/mapping/CompoundPrimaryKeyUnitTests.java index 66e7dc635..3bb750000 100755 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/mapping/CompoundPrimaryKeyUnitTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/mapping/CompoundPrimaryKeyUnitTests.java @@ -23,6 +23,7 @@ import java.util.Date; import org.junit.Before; import org.junit.Test; import org.springframework.cassandra.core.PrimaryKeyType; +import org.springframework.data.mapping.model.Property; import org.springframework.data.util.ClassTypeInformation; import org.springframework.util.ReflectionUtils; @@ -31,6 +32,7 @@ import org.springframework.util.ReflectionUtils; * * @author Alex Shvid * @author Matthew T. Adams + * @author Mark Paluch */ public class CompoundPrimaryKeyUnitTests { @@ -61,12 +63,12 @@ public class CompoundPrimaryKeyUnitTests { @Test public void checkIdProperty() { Field id = ReflectionUtils.findField(Timeline.class, "id"); - CassandraPersistentProperty property = getPropertyFor(id); + CassandraPersistentProperty property = getPropertyFor(Property.of(id)); assertThat(property.isIdProperty()).isTrue(); assertThat(property.isCompositePrimaryKey()).isTrue(); } - private CassandraPersistentProperty getPropertyFor(Field field) { - return new BasicCassandraPersistentProperty(field, null, entity, new CassandraSimpleTypeHolder()); + private CassandraPersistentProperty getPropertyFor(Property property) { + return new BasicCassandraPersistentProperty(property, entity, new CassandraSimpleTypeHolder()); } } diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/mapping/CreateTableSpecificationBasicCassandraMappingContextUnitTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/mapping/CreateTableSpecificationBasicCassandraMappingContextUnitTests.java index cd74d79a1..2a46e0dfb 100755 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/mapping/CreateTableSpecificationBasicCassandraMappingContextUnitTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/mapping/CreateTableSpecificationBasicCassandraMappingContextUnitTests.java @@ -71,7 +71,7 @@ public class CreateTableSpecificationBasicCassandraMappingContextUnitTests { @Test // DATACASS-296 public void customConversionTestShouldCreateCorrectTableDefinition() { - CassandraPersistentEntity persistentEntity = ctx.getPersistentEntity(Employee.class); + CassandraPersistentEntity persistentEntity = ctx.getRequiredPersistentEntity(Employee.class); CreateTableSpecification specification = ctx.getCreateTableSpecificationFor(persistentEntity); @@ -97,7 +97,7 @@ public class CreateTableSpecificationBasicCassandraMappingContextUnitTests { @Test // DATACASS-296 public void customConversionTestShouldHonorTypeAnnotationAndCreateCorrectTableDefinition() { - CassandraPersistentEntity persistentEntity = ctx.getPersistentEntity(Employee.class); + CassandraPersistentEntity persistentEntity = ctx.getRequiredPersistentEntity(Employee.class); CreateTableSpecification specification = ctx.getCreateTableSpecificationFor(persistentEntity); @@ -308,7 +308,7 @@ public class CreateTableSpecificationBasicCassandraMappingContextUnitTests { CustomConversions customConversions = new CustomConversions(Collections.EMPTY_LIST); ctx.setCustomConversions(customConversions); - CassandraPersistentEntity persistentEntity = ctx.getPersistentEntity(persistentEntityClass); + CassandraPersistentEntity persistentEntity = ctx.getRequiredPersistentEntity(persistentEntityClass); return ctx.getCreateTableSpecificationFor(persistentEntity); } diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/mapping/ForceQuotedPropertiesSimpleUnitTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/mapping/ForceQuotedPropertiesSimpleUnitTests.java index 94ff14a92..78ebfd685 100755 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/mapping/ForceQuotedPropertiesSimpleUnitTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/mapping/ForceQuotedPropertiesSimpleUnitTests.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.springframework.data.cassandra.mapping; import static org.assertj.core.api.Assertions.*; @@ -45,10 +44,10 @@ public class ForceQuotedPropertiesSimpleUnitTests { @Test public void testImplicit() { - CassandraPersistentEntity entity = context.getPersistentEntity(Implicit.class); + CassandraPersistentEntity entity = context.getRequiredPersistentEntity(Implicit.class); - CassandraPersistentProperty primaryKey = entity.getPersistentProperty("primaryKey"); - CassandraPersistentProperty aString = entity.getPersistentProperty("aString"); + CassandraPersistentProperty primaryKey = entity.getRequiredPersistentProperty("primaryKey"); + CassandraPersistentProperty aString = entity.getRequiredPersistentProperty("aString"); assertThat(primaryKey.getColumnName().toCql()).isEqualTo("\"primaryKey\""); assertThat(aString.getColumnName().toCql()).isEqualTo("\"aString\""); @@ -65,10 +64,10 @@ public class ForceQuotedPropertiesSimpleUnitTests { @Test public void testDefault() { - CassandraPersistentEntity entity = context.getPersistentEntity(Default.class); + CassandraPersistentEntity entity = context.getRequiredPersistentEntity(Default.class); - CassandraPersistentProperty primaryKey = entity.getPersistentProperty("primaryKey"); - CassandraPersistentProperty aString = entity.getPersistentProperty("aString"); + CassandraPersistentProperty primaryKey = entity.getRequiredPersistentProperty("primaryKey"); + CassandraPersistentProperty aString = entity.getRequiredPersistentProperty("aString"); assertThat(primaryKey.getColumnName().toCql()).isEqualTo("primarykey"); assertThat(aString.getColumnName().toCql()).isEqualTo("astring"); @@ -85,10 +84,10 @@ public class ForceQuotedPropertiesSimpleUnitTests { @Test public void testExplicit() { - CassandraPersistentEntity entity = context.getPersistentEntity(Explicit.class); + CassandraPersistentEntity entity = context.getRequiredPersistentEntity(Explicit.class); - CassandraPersistentProperty primaryKey = entity.getPersistentProperty("primaryKey"); - CassandraPersistentProperty aString = entity.getPersistentProperty("aString"); + CassandraPersistentProperty primaryKey = entity.getRequiredPersistentProperty("primaryKey"); + CassandraPersistentProperty aString = entity.getRequiredPersistentProperty("aString"); assertThat(primaryKey.getColumnName().toCql()).isEqualTo("\"" + EXPLICIT_PRIMARY_KEY_NAME + "\""); assertThat(aString.getColumnName().toCql()).isEqualTo("\"" + EXPLICIT_COLUMN_NAME + "\""); @@ -105,19 +104,19 @@ public class ForceQuotedPropertiesSimpleUnitTests { @Test public void testImplicitComposite() { - CassandraPersistentEntity key = context.getPersistentEntity(ImplicitKey.class); + CassandraPersistentEntity key = context.getRequiredPersistentEntity(ImplicitKey.class); - CassandraPersistentProperty stringZero = key.getPersistentProperty("stringZero"); - CassandraPersistentProperty stringOne = key.getPersistentProperty("stringOne"); + CassandraPersistentProperty stringZero = key.getRequiredPersistentProperty("stringZero"); + CassandraPersistentProperty stringOne = key.getRequiredPersistentProperty("stringOne"); assertThat(stringZero.getColumnName().toCql()).isEqualTo("\"stringZero\""); assertThat(stringOne.getColumnName().toCql()).isEqualTo("\"stringOne\""); List names = Arrays - .asList(new CqlIdentifier[] { quotedCqlId("stringZero"), quotedCqlId("stringOne") }); - CassandraPersistentEntity entity = context.getPersistentEntity(ImplicitComposite.class); + .asList(quotedCqlId("stringZero"), quotedCqlId("stringOne")); + CassandraPersistentEntity entity = context.getRequiredPersistentEntity(ImplicitComposite.class); - assertThat(entity.getPersistentProperty("primaryKey").getColumnNames()).isEqualTo(names); + assertThat(entity.getRequiredPersistentProperty("primaryKey").getColumnNames()).isEqualTo(names); } @PrimaryKeyClass @@ -141,20 +140,20 @@ public class ForceQuotedPropertiesSimpleUnitTests { @Test public void testDefaultComposite() { - CassandraPersistentEntity key = context.getPersistentEntity(DefaultKey.class); + CassandraPersistentEntity key = context.getRequiredPersistentEntity(DefaultKey.class); - CassandraPersistentProperty stringZero = key.getPersistentProperty("stringZero"); - CassandraPersistentProperty stringOne = key.getPersistentProperty("stringOne"); + CassandraPersistentProperty stringZero = key.getRequiredPersistentProperty("stringZero"); + CassandraPersistentProperty stringOne = key.getRequiredPersistentProperty("stringOne"); assertThat(stringZero.getColumnName()).isEqualTo(CqlIdentifier.cqlId("stringZero")); assertThat(stringOne.getColumnName()).isEqualTo(CqlIdentifier.cqlId("stringOne")); assertThat(stringZero.getColumnName().toCql()).isEqualTo("stringzero"); assertThat(stringOne.getColumnName().toCql()).isEqualTo("stringone"); - List names = Arrays.asList(new CqlIdentifier[] { cqlId("stringZero"), cqlId("stringOne") }); - CassandraPersistentEntity entity = context.getPersistentEntity(DefaultComposite.class); + List names = Arrays.asList(cqlId("stringZero"), cqlId("stringOne")); + CassandraPersistentEntity entity = context.getRequiredPersistentEntity(DefaultComposite.class); - assertThat(entity.getPersistentProperty("primaryKey").getColumnNames()).isEqualTo(names); + assertThat(entity.getRequiredPersistentProperty("primaryKey").getColumnNames()).isEqualTo(names); } @PrimaryKeyClass @@ -178,10 +177,10 @@ public class ForceQuotedPropertiesSimpleUnitTests { @Test public void testExplicitComposite() { - CassandraPersistentEntity key = context.getPersistentEntity(ExplicitKey.class); + CassandraPersistentEntity key = context.getRequiredPersistentEntity(ExplicitKey.class); - CassandraPersistentProperty stringZero = key.getPersistentProperty("stringZero"); - CassandraPersistentProperty stringOne = key.getPersistentProperty("stringOne"); + CassandraPersistentProperty stringZero = key.getRequiredPersistentProperty("stringZero"); + CassandraPersistentProperty stringOne = key.getRequiredPersistentProperty("stringOne"); assertThat(stringZero.getColumnName()) // .isEqualTo(CqlIdentifier.cqlId("TheFirstKeyField", true)) // @@ -191,10 +190,10 @@ public class ForceQuotedPropertiesSimpleUnitTests { assertThat(stringOne.getColumnName().toCql()).isEqualTo("\"" + EXPLICIT_KEY_1 + "\""); List names = Arrays - .asList(new CqlIdentifier[] { quotedCqlId(EXPLICIT_KEY_0), quotedCqlId(EXPLICIT_KEY_1) }); - CassandraPersistentEntity entity = context.getPersistentEntity(ExplicitComposite.class); + .asList(quotedCqlId(EXPLICIT_KEY_0), quotedCqlId(EXPLICIT_KEY_1)); + CassandraPersistentEntity entity = context.getRequiredPersistentEntity(ExplicitComposite.class); - assertThat(entity.getPersistentProperty("primaryKey").getColumnNames()).isEqualTo(names); + assertThat(entity.getRequiredPersistentProperty("primaryKey").getColumnNames()).isEqualTo(names); } @PrimaryKeyClass diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/mapping/PrimaryKeyClassEntityMetadataVerifierUnitTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/mapping/PrimaryKeyClassEntityMetadataVerifierUnitTests.java index 5d426f9c7..5a9007208 100644 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/mapping/PrimaryKeyClassEntityMetadataVerifierUnitTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/mapping/PrimaryKeyClassEntityMetadataVerifierUnitTests.java @@ -143,7 +143,7 @@ public class PrimaryKeyClassEntityMetadataVerifierUnitTests { } private CassandraPersistentEntity getEntity(Class entityClass) { - return context.getPersistentEntity(entityClass); + return context.getRequiredPersistentEntity(entityClass); } interface MyInterface { diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/repository/query/CassandraQueryCreatorUnitTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/repository/query/CassandraQueryCreatorUnitTests.java index 38ef84680..59cfb404a 100644 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/repository/query/CassandraQueryCreatorUnitTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/repository/query/CassandraQueryCreatorUnitTests.java @@ -275,8 +275,8 @@ public class CassandraQueryCreatorUnitTests { @SuppressWarnings("unchecked") private CassandraEntityInformation getEntityInformation(final Class entityClass) { - return new MappingCassandraEntityInformation( - (CassandraPersistentEntity) context.getPersistentEntity(entityClass), converter); + return new MappingCassandraEntityInformation<>( + (CassandraPersistentEntity) context.getRequiredPersistentEntity(entityClass), converter); } @Table diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/repository/query/ConvertingParameterAccessorUnitTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/repository/query/ConvertingParameterAccessorUnitTests.java index 3e3887415..92fe4d927 100755 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/repository/query/ConvertingParameterAccessorUnitTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/repository/query/ConvertingParameterAccessorUnitTests.java @@ -22,6 +22,7 @@ import java.time.LocalDate; import java.util.Collections; import java.util.Iterator; import java.util.List; +import java.util.Optional; import org.junit.Before; import org.junit.Test; @@ -143,9 +144,9 @@ public class ConvertingParameterAccessorUnitTests { public void shouldProvideTypeBasedOnPropertyType() { when(mockProperty.getDataType()).thenReturn(DataType.varchar()); - when(mockProperty.findAnnotation(CassandraType.class)).thenReturn(mock(CassandraType.class)); + when(mockProperty.findAnnotation(CassandraType.class)).thenReturn(Optional.of(mock(CassandraType.class))); when(mockParameterAccessor.getParameterType(0)).thenReturn((Class) String.class); - assertThat(convertingParameterAccessor.getDataType(0, mockProperty)).isEqualTo(DataType.varchar()); + assertThat(convertingParameterAccessor.getDataType(0, Optional.of(mockProperty))).isEqualTo(DataType.varchar()); } } diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/repository/query/StubParameterAccessor.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/repository/query/StubParameterAccessor.java index 352e98e3d..0e1f2377c 100644 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/repository/query/StubParameterAccessor.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/repository/query/StubParameterAccessor.java @@ -17,6 +17,7 @@ package org.springframework.data.cassandra.repository.query; import java.util.Arrays; import java.util.Iterator; +import java.util.Optional; import org.springframework.data.cassandra.convert.CassandraConverter; import org.springframework.data.cassandra.mapping.CassandraType; @@ -74,8 +75,8 @@ class StubParameterAccessor implements CassandraParameterAccessor { } @Override - public Class getDynamicProjection() { - return null; + public Optional> getDynamicProjection() { + return Optional.empty(); } @Override diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/repository/support/CassandraRepositoryFactoryUnitTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/repository/support/CassandraRepositoryFactoryUnitTests.java index 25201cd07..46a42fb1c 100644 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/repository/support/CassandraRepositoryFactoryUnitTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/repository/support/CassandraRepositoryFactoryUnitTests.java @@ -52,13 +52,15 @@ public class CassandraRepositoryFactoryUnitTests { @Before public void setUp() { + when(template.getConverter()).thenReturn(converter); when(converter.getMappingContext()).thenReturn(mappingContext); } @Test // DATACASS-7 public void usesMappingCassandraEntityInformationIfMappingContextSet() { - when(mappingContext.getPersistentEntity(Person.class)).thenReturn(entity); + + when(mappingContext.getRequiredPersistentEntity(Person.class)).thenReturn(entity); when(entity.getType()).thenReturn(Person.class); CassandraRepositoryFactory repositoryFactory = new CassandraRepositoryFactory(template); @@ -71,7 +73,8 @@ public class CassandraRepositoryFactoryUnitTests { @Test // DATACASS-7 public void createsRepositoryWithIdTypeLong() { - when(mappingContext.getPersistentEntity(Person.class)).thenReturn(entity); + + when(mappingContext.getRequiredPersistentEntity(Person.class)).thenReturn(entity); when(entity.getType()).thenReturn(Person.class); CassandraRepositoryFactory repositoryFactory = new CassandraRepositoryFactory(template); diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/repository/support/ReactiveCassandraRepositoryFactoryUnitTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/repository/support/ReactiveCassandraRepositoryFactoryUnitTests.java index b4835f95f..c2886d4f9 100644 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/repository/support/ReactiveCassandraRepositoryFactoryUnitTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/repository/support/ReactiveCassandraRepositoryFactoryUnitTests.java @@ -56,7 +56,7 @@ public class ReactiveCassandraRepositoryFactoryUnitTests { @Test // DATACASS-335 public void usesMappingCassandraEntityInformationIfMappingContextSet() { - when(mappingContext.getPersistentEntity(Person.class)).thenReturn(entity); + when(mappingContext.getRequiredPersistentEntity(Person.class)).thenReturn(entity); when(entity.getType()).thenReturn(Person.class); ReactiveCassandraRepositoryFactory repositoryFactory = new ReactiveCassandraRepositoryFactory(template); @@ -70,7 +70,7 @@ public class ReactiveCassandraRepositoryFactoryUnitTests { @Test // DATACASS-335 public void createsRepositoryWithIdTypeLong() { - when(mappingContext.getPersistentEntity(Person.class)).thenReturn(entity); + when(mappingContext.getRequiredPersistentEntity(Person.class)).thenReturn(entity); when(entity.getType()).thenReturn(Person.class); ReactiveCassandraRepositoryFactory repositoryFactory = new ReactiveCassandraRepositoryFactory(template); diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/repository/support/SimpleCassandraRepositoryIntegrationTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/repository/support/SimpleCassandraRepositoryIntegrationTests.java index 351f84364..4c1344b7c 100644 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/repository/support/SimpleCassandraRepositoryIntegrationTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/repository/support/SimpleCassandraRepositoryIntegrationTests.java @@ -19,6 +19,7 @@ import static org.assertj.core.api.Assertions.*; import java.util.Arrays; import java.util.List; +import java.util.Optional; import org.junit.Before; import org.junit.Test; @@ -124,17 +125,17 @@ public class SimpleCassandraRepositoryIntegrationTests extends AbstractKeyspaceC @Test // DATACASS-396 public void findOneShouldReturnObject() { - Person person = repository.findOne(dave.getId()); + Optional person = repository.findOne(dave.getId()); - assertThat(person).isEqualTo(dave); + assertThat(person).contains(dave); } @Test // DATACASS-396 public void findOneShouldCompleteWithoutValueForAbsentObject() { - Person person = repository.findOne("unknown"); + Optional person = repository.findOne("unknown"); - assertThat(person).isNull(); + assertThat(person).isEmpty(); } @Test // DATACASS-396, DATACASS-416 @@ -193,10 +194,14 @@ public class SimpleCassandraRepositoryIntegrationTests extends AbstractKeyspaceC assertThat(saved).isEqualTo(saved); - Person loaded = repository.findOne(dave.getId()); + Optional loaded = repository.findOne(dave.getId()); - assertThat(loaded.getFirstname()).isEqualTo(dave.getFirstname()); - assertThat(loaded.getLastname()).isEqualTo(dave.getLastname()); + assertThat(loaded).isPresent(); + + loaded.ifPresent(actual -> { + assertThat(actual.getFirstname()).isEqualTo(dave.getFirstname()); + assertThat(actual.getLastname()).isEqualTo(dave.getLastname()); + }); } @Test // DATACASS-396 @@ -208,9 +213,9 @@ public class SimpleCassandraRepositoryIntegrationTests extends AbstractKeyspaceC assertThat(saved).isEqualTo(person); - Person loaded = repository.findOne(person.getId()); + Optional loaded = repository.findOne(person.getId()); - assertThat(loaded).isEqualTo(person); + assertThat(loaded).contains(person); } @Test // DATACASS-396, DATACASS-416 @@ -237,11 +242,11 @@ public class SimpleCassandraRepositoryIntegrationTests extends AbstractKeyspaceC assertThat(saved).hasSize(2); - Person persistentDave = repository.findOne(dave.getId()); - assertThat(persistentDave).isEqualTo(dave); + Optional persistentDave = repository.findOne(dave.getId()); + assertThat(persistentDave).contains(dave); - Person persistentHomer = repository.findOne(person.getId()); - assertThat(persistentHomer).isEqualTo(person); + Optional persistentHomer = repository.findOne(person.getId()); + assertThat(persistentHomer).contains(person); } @Test // DATACASS-396, DATACASS-416 @@ -259,9 +264,9 @@ public class SimpleCassandraRepositoryIntegrationTests extends AbstractKeyspaceC repository.delete(dave.getId()); - Person loaded = repository.findOne(dave.getId()); + Optional loaded = repository.findOne(dave.getId()); - assertThat(loaded).isNull(); + assertThat(loaded).isPresent(); } @Test // DATACASS-396 @@ -269,9 +274,9 @@ public class SimpleCassandraRepositoryIntegrationTests extends AbstractKeyspaceC repository.delete(dave); - Person loaded = repository.findOne(dave.getId()); + Optional loaded = repository.findOne(dave.getId()); - assertThat(loaded).isNull(); + assertThat(loaded).isPresent(); } @Test // DATACASS-396 @@ -279,9 +284,9 @@ public class SimpleCassandraRepositoryIntegrationTests extends AbstractKeyspaceC repository.delete(Arrays.asList(dave, boyd)); - Person loaded = repository.findOne(boyd.getId()); + Optional loaded = repository.findOne(boyd.getId()); - assertThat(loaded).isNull(); + assertThat(loaded).isPresent(); } interface PersonRepostitory extends TypedIdCassandraRepository {} diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/collections/CollectionsRowValueProviderIntegrationTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/collections/CollectionsRowValueProviderIntegrationTests.java index 2760d273c..888b1f1e6 100755 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/collections/CollectionsRowValueProviderIntegrationTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/collections/CollectionsRowValueProviderIntegrationTests.java @@ -84,12 +84,11 @@ public class CollectionsRowValueProviderIntegrationTests extends AbstractKeyspac Select select = QueryBuilder.select().all().from("bookHistory"); select.where(QueryBuilder.eq("isbn", "123456-1")); - BookHistory b = operations.selectOne(select, BookHistory.class); - - assertThat(b.getCheckOuts()).isNotNull(); - assertThat("Spring Data Cassandra Guide").isEqualTo(b.getTitle()); - assertThat("Cassandra Guru").isEqualTo(b.getAuthor()); + BookHistory result = operations.selectOne(select, BookHistory.class); + assertThat(result.getCheckOuts()).isNotNull(); + assertThat(result.getTitle()).isEqualTo("Spring Data Cassandra Guide"); + assertThat(result.getAuthor()).isEqualTo("Cassandra Guru"); } @Test @@ -120,12 +119,12 @@ public class CollectionsRowValueProviderIntegrationTests extends AbstractKeyspac Select select = QueryBuilder.select().all().from("bookReference"); select.where(QueryBuilder.eq("isbn", "123456-1")); - BookReference b = operations.selectOne(select, BookReference.class); + BookReference result = operations.selectOne(select, BookReference.class); - assertThat(b.getReferences()).isNotNull(); - assertThat(b.getBookmarks()).isNotNull(); - assertThat("Spring Data Cassandra Guide").isEqualTo(b.getTitle()); - assertThat("Cassandra Guru").isEqualTo(b.getAuthor()); + assertThat(result.getReferences()).isNotNull(); + assertThat(result.getBookmarks()).isNotNull(); + assertThat(result.getTitle()).isEqualTo("Spring Data Cassandra Guide"); + assertThat(result.getAuthor()).isEqualTo("Cassandra Guru"); } } diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/composites/Comment.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/composites/Comment.java deleted file mode 100644 index 3452ddd1b..000000000 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/composites/Comment.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright 2013-2017 the original author or authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.data.cassandra.test.integration.composites; - -import org.springframework.data.cassandra.mapping.PrimaryKey; -import org.springframework.data.cassandra.mapping.Table; -import org.springframework.util.Assert; - -/** - * This is an example of dynamic table (wide row). PartitionKey (former RowId) is pk.author. ClusteredColumn (former - * Column Id) is pk.time - * - * @author Alex Shvid - * @author Matthew T. Adams - */ -@Table("comments") -public class Comment { - - @PrimaryKey private CommentKey pk; - - private String text; - - protected Comment() {} - - public Comment(String author, String company) { - this(new CommentKey(author, company)); - } - - public Comment(CommentKey pk) { - Assert.notNull(pk, "CommentKey must not be null"); - this.pk = pk; - } - - public CommentKey getId() { - return pk; - } - - public void setPk(CommentKey pk) { - this.pk = pk; - } - - public String getText() { - return text; - } - - public void setText(String text) { - this.text = text; - } - - @Override - public boolean equals(Object that) { - - if (this == that) { - return true; - } - if (that == null) { - return false; - } - if (!(that instanceof Comment)) { - return false; - } - - Comment other = (Comment) that; - - if (this.pk == null) { - return other.pk == null; - } - - return this.pk.equals(other.pk); - } - - @Override - public int hashCode() { - return pk.hashCode(); - } -} diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/composites/CommentKey.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/composites/CommentKey.java deleted file mode 100644 index 5aa119db1..000000000 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/composites/CommentKey.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright 2013-2017 the original author or authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.data.cassandra.test.integration.composites; - -import java.io.Serializable; - -import org.springframework.cassandra.core.PrimaryKeyType; -import org.springframework.data.cassandra.mapping.PrimaryKeyClass; -import org.springframework.data.cassandra.mapping.PrimaryKeyColumn; - -/** - * This is an example of dynamic table (wide row) that creates each time new column with timestamp. - * - * @author Alex Shvid - * @author Matthew T. Adams - */ -@PrimaryKeyClass -public class CommentKey implements Serializable { - - private static final long serialVersionUID = -7871651389236401141L; - - @PrimaryKeyColumn(ordinal = 0, type = PrimaryKeyType.PARTITIONED) private String author; - - @PrimaryKeyColumn(ordinal = 1) private String company; - - public CommentKey(String author, String company) { - setAuthor(author); - setCompany(company); - } - - public String getAuthor() { - return author; - } - - protected void setAuthor(String author) { - this.author = author; - } - - public String getCompany() { - return company; - } - - public void setCompany(String company) { - this.company = company; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((author == null) ? 0 : author.hashCode()); - result = prime * result + ((company == null) ? 0 : company.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - CommentKey other = (CommentKey) obj; - if (author == null) { - if (other.author != null) - return false; - } else if (!author.equals(other.author)) - return false; - if (company == null) { - if (other.company != null) - return false; - } else if (!company.equals(other.company)) - return false; - return true; - } -} diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/composites/CommentRepository.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/composites/CommentRepository.java deleted file mode 100644 index 1e6d43de7..000000000 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/composites/CommentRepository.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2013-2017 the original author or authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.data.cassandra.test.integration.composites; - -import org.springframework.data.cassandra.repository.TypedIdCassandraRepository; - -public interface CommentRepository extends TypedIdCassandraRepository {} diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/composites/CommentRepositoryIntegrationTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/composites/CommentRepositoryIntegrationTests.java deleted file mode 100755 index b6e89cd52..000000000 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/composites/CommentRepositoryIntegrationTests.java +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright 2013-2017 the original author or authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.data.cassandra.test.integration.composites; - -import static org.assertj.core.api.Assertions.*; - -import org.springframework.data.cassandra.core.CassandraOperations; - -/** - * Tests for {@link CommentRepository}. - * - * @author Matthew T. Adams - */ -public class CommentRepositoryIntegrationTests { - - CommentRepository repository; - CassandraOperations template; - - public CommentRepositoryIntegrationTests() {} - - public CommentRepositoryIntegrationTests(CommentRepository repository, CassandraOperations template) { - this.repository = repository; - this.template = template; - } - - public void before() { - repository.deleteAll(); - } - - public void testInsert() { - - String author = "testAuthorInsert"; - String company = "testCompanyInsert"; - - Comment c = new Comment(author, company); - c.setText("testTextInsert"); - - CommentKey key = c.getId(); - - repository.save(c); - - Comment retrieved = repository.findOne(key); - - assertThat(retrieved).isNotSameAs(c); - assertThat(retrieved).isEqualTo(c); - assertThat(retrieved.getText()).isEqualTo(c.getText()); - } - - public void testUpdateNonKeyField() { - - String author = "testAuthorUpdate"; - String company = "testCompanyUpdate"; - - Comment c = new Comment(author, company); - c.setText("testTextUpdate"); - - CommentKey key = c.getId(); - - repository.save(c); - - Comment retrieved = repository.findOne(key); - - assertThat(retrieved).isNotSameAs(c); - assertThat(retrieved).isEqualTo(c); - assertThat(retrieved.getText()).isEqualTo(c.getText()); - - String newText = "x" + retrieved.getText(); - retrieved.setText(newText); - - repository.save(retrieved); - - Comment updated = repository.findOne(key); - - assertThat(updated).isNotSameAs(retrieved); - assertThat(updated.getText()).isEqualTo(newText); - } - - public void testDelete() { - - String author = "testAuthorDelete"; - String company = "testCompanyDelete"; - - Comment c = new Comment(author, company); - c.setText("testTextDelete"); - - CommentKey key = c.getId(); - - repository.save(c); - - Comment retrieved = repository.findOne(key); - - assertThat(retrieved).isNotSameAs(c); - assertThat(retrieved).isEqualTo(c); - assertThat(retrieved.getText()).isEqualTo(c.getText()); - - repository.delete(retrieved); - - assertThat(repository.findOne(key)).isNull(); - } -} diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/composites/CommentRepositoryJavaConfigIntegrationTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/composites/CommentRepositoryJavaConfigIntegrationTests.java deleted file mode 100755 index d2d798f6b..000000000 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/composites/CommentRepositoryJavaConfigIntegrationTests.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright 2013-2017 the original author or authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.data.cassandra.test.integration.composites; - -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.core.CassandraOperations; -import org.springframework.data.cassandra.repository.config.EnableCassandraRepositories; -import org.springframework.data.cassandra.test.integration.repository.simple.UserRepository; -import org.springframework.data.cassandra.test.integration.support.AbstractSpringDataEmbeddedCassandraIntegrationTest; -import org.springframework.data.cassandra.test.integration.support.IntegrationTestConfig; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - -/** - * Base class for Java config tests for {@link UserRepository}. - * - * @author Matthew T. Adams - * @author Mark Paluch - */ -@RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration -public class CommentRepositoryJavaConfigIntegrationTests extends AbstractSpringDataEmbeddedCassandraIntegrationTest { - - @Configuration - @EnableCassandraRepositories(basePackageClasses = CommentRepository.class) - public static class Config extends IntegrationTestConfig { - - @Override - public String[] getEntityBasePackages() { - return new String[] { Comment.class.getPackage().getName() }; - } - } - - @Autowired protected CommentRepository repository; - - @Autowired protected CassandraOperations template; - - CommentRepositoryIntegrationTests tests; - - @Before - public void before() { - tests = new CommentRepositoryIntegrationTests(repository, template); - tests.before(); - } - - @Test - public void testInsert() { - tests.testInsert(); - } - - @Test - public void testDelete() { - tests.testDelete(); - } - - @Test - public void testUpdateNonKeyField() { - tests.testUpdateNonKeyField(); - } -} diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/composites/CommentRepositoryXmlConfigIntegrationTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/composites/CommentRepositoryXmlConfigIntegrationTests.java deleted file mode 100755 index 4a410cdd3..000000000 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/composites/CommentRepositoryXmlConfigIntegrationTests.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright 2013-2017 the original author or authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.data.cassandra.test.integration.composites; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.cassandra.core.CassandraOperations; -import org.springframework.data.cassandra.test.integration.repository.simple.UserRepository; -import org.springframework.data.cassandra.test.integration.support.AbstractSpringDataEmbeddedCassandraIntegrationTest; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - -/** - * Base class for xml config tests for {@link UserRepository}. - * - * @author Matthew T. Adams - * @author Mark Paluch - */ -@RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration -public class CommentRepositoryXmlConfigIntegrationTests extends AbstractSpringDataEmbeddedCassandraIntegrationTest { - - @Autowired private CommentRepository repository; - - @Autowired private CassandraOperations template; - - private CommentRepositoryIntegrationTests tests; - - @Before - public void setUp() throws InterruptedException { - tests = new CommentRepositoryIntegrationTests(repository, template); - tests.before(); - } - - @Test - public void testInsert() { - tests.testInsert(); - } - - @Test - public void testDelete() { - tests.testDelete(); - } - - @Test - public void testUpdateNonKeyField() { - tests.testUpdateNonKeyField(); - } -} diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/composites/Notification.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/composites/Notification.java deleted file mode 100644 index fb24f5dd1..000000000 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/composites/Notification.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright 2013-2017 the original author or authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.data.cassandra.test.integration.composites; - -import java.util.Date; - -import org.springframework.data.annotation.Id; -import org.springframework.data.cassandra.mapping.Indexed; -import org.springframework.data.cassandra.mapping.Table; - -/** - * This is an example of dynamic table that creates each time new column with Notification timestamp. By default it is - * active Notification until user deactivate it. This table uses index on the field active to access in WHERE cause only - * for active notifications. - * - * @author Alex Shvid - */ -@Table("notifications") -public class Notification { - - /* - * Primary Key - */ - @Id private NotificationPK pk; - - @Indexed private boolean active; - - /* - * Reference data - */ - - private String type; // comment, post - private String refAuthor; - private Date refTime; - - public NotificationPK getPk() { - return pk; - } - - public void setPk(NotificationPK pk) { - this.pk = pk; - } - - public boolean isActive() { - return active; - } - - public void setActive(boolean active) { - this.active = active; - } - - public String getType() { - return type; - } - - public void setType(String type) { - this.type = type; - } - - public String getRefAuthor() { - return refAuthor; - } - - public void setRefAuthor(String refAuthor) { - this.refAuthor = refAuthor; - } - - public Date getRefTime() { - return refTime; - } - - public void setRefTime(Date refTime) { - this.refTime = refTime; - } - -} diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/composites/NotificationPK.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/composites/NotificationPK.java deleted file mode 100644 index 622dcc818..000000000 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/composites/NotificationPK.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright 2013-2017 the original author or authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.data.cassandra.test.integration.composites; - -import java.io.Serializable; -import java.util.Date; - -import org.springframework.cassandra.core.PrimaryKeyType; -import org.springframework.data.cassandra.mapping.CassandraType; -import org.springframework.data.cassandra.mapping.PrimaryKeyClass; -import org.springframework.data.cassandra.mapping.PrimaryKeyColumn; - -import com.datastax.driver.core.DataType; - -/** - * This is an example of dynamic table that creates each time new column with Notification timestamp. By default it is - * active Notification until user deactivate it. This table uses index on the field active to access in WHERE cause only - * for active notifications. - * - * @author Alex Shvid - */ -@PrimaryKeyClass -public class NotificationPK implements Serializable { - - private static final long serialVersionUID = -5041736242014855732L; - - /* - * Row ID - */ - @PrimaryKeyColumn(ordinal = 0, type = PrimaryKeyType.PARTITIONED) private String username; - - /* - * Clustered Column - */ - @PrimaryKeyColumn(ordinal = 1) @CassandraType(type = DataType.Name.TIMESTAMP) private Date time; - - public String getUsername() { - return username; - } - - public void setUsername(String username) { - this.username = username; - } - - public Date getTime() { - return time; - } - - public void setTime(Date time) { - this.time = time; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((time == null) ? 0 : time.hashCode()); - result = prime * result + ((username == null) ? 0 : username.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - NotificationPK other = (NotificationPK) obj; - if (time == null) { - if (other.time != null) - return false; - } else if (!time.equals(other.time)) - return false; - if (username == null) { - if (other.username != null) - return false; - } else if (!username.equals(other.username)) - return false; - return true; - } - -} diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/composites/Post.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/composites/Post.java deleted file mode 100644 index 9c6ec571d..000000000 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/composites/Post.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright 2013-2017 the original author or authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.data.cassandra.test.integration.composites; - -import java.util.Date; -import java.util.Map; -import java.util.Set; - -import org.springframework.data.annotation.Id; -import org.springframework.data.cassandra.mapping.Table; - -/** - * This is an example of dynamic table that creates each time new column with Post timestamp. It is possible to use a - * static table for posts and identify them by PostId(UUID), but in this case we need to use MapReduce for Big Data to - * find posts for particular user, so it is better to have index (userId) -> index (post time) architecture. It helps a - * lot to build eventually a search index for the particular user. - * - * @author Alex Shvid - */ -@Table("posts") -public class Post { - - /* - * Primary Key - */ - @Id private PostPK pk; - - private String type; // status, share - - private String text; - private Set resources; - private Map comments; - private Set likes; - private Set followers; - - public PostPK getPk() { - return pk; - } - - public void setPk(PostPK pk) { - this.pk = pk; - } - - public String getType() { - return type; - } - - public void setType(String type) { - this.type = type; - } - - public String getText() { - return text; - } - - public void setText(String text) { - this.text = text; - } - - public Set getResources() { - return resources; - } - - public void setResources(Set resources) { - this.resources = resources; - } - - public Map getComments() { - return comments; - } - - public void setComments(Map comments) { - this.comments = comments; - } - - public Set getLikes() { - return likes; - } - - public void setLikes(Set likes) { - this.likes = likes; - } - - public Set getFollowers() { - return followers; - } - - public void setFollowers(Set followers) { - this.followers = followers; - } - -} diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/composites/PostPK.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/composites/PostPK.java deleted file mode 100644 index 35cc895fe..000000000 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/composites/PostPK.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright 2013-2017 the original author or authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.data.cassandra.test.integration.composites; - -import java.io.Serializable; -import java.util.Date; - -import org.springframework.cassandra.core.PrimaryKeyType; -import org.springframework.data.cassandra.mapping.PrimaryKeyClass; -import org.springframework.data.cassandra.mapping.PrimaryKeyColumn; - -/** - * This is an example of dynamic table that creates each time new column with Post timestamp. It is possible to use a - * static table for posts and identify them by PostId(UUID), but in this case we need to use MapReduce for Big Data to - * find posts for particular user, so it is better to have index (userId) -> index (post time) architecture. It helps a - * lot to build eventually a search index for the particular user. - * - * @author Alex Shvid - */ - -@PrimaryKeyClass -public class PostPK implements Serializable { - - private static final long serialVersionUID = 2390757126054483315L; - - @PrimaryKeyColumn(ordinal = 0, type = PrimaryKeyType.PARTITIONED) private String author; - - @PrimaryKeyColumn(ordinal = 1) private Date time; - - public String getAuthor() { - return author; - } - - public void setAuthor(String author) { - this.author = author; - } - - public Date getTime() { - return time; - } - - public void setTime(Date time) { - this.time = time; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((author == null) ? 0 : author.hashCode()); - result = prime * result + ((time == null) ? 0 : time.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - PostPK other = (PostPK) obj; - if (author == null) { - if (other.author != null) - return false; - } else if (!author.equals(other.author)) - return false; - if (time == null) { - if (other.time != null) - return false; - } else if (!time.equals(other.time)) - return false; - return true; - } - -} diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/composites/Timeline.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/composites/Timeline.java deleted file mode 100644 index 25eed6644..000000000 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/composites/Timeline.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2013-2017 the original author or authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.data.cassandra.test.integration.composites; - -import java.util.Date; - -import org.springframework.data.annotation.Id; -import org.springframework.data.cassandra.mapping.Table; - -/** - * This is an example of the users timeline dynamic table, where all columns are dynamically created by @ColumnId field - * value. The rest fields are places in Cassandra value. Timeline entity is used to store user's status updates that it - * follows in the site. Timeline always ordered by @ColumnId field and we can retrieve last top status updates by using - * limits. - * - * @author Alex Shvid - */ -@Table("timeline") -public class Timeline { - - /* - * Row ID - */ - @Id private TimelinePK pk; - - /* - * Reference to the post by author and postUID - */ - private String author; - private Date postTime; - - public TimelinePK getPk() { - return pk; - } - - public void setPk(TimelinePK pk) { - this.pk = pk; - } - - public String getAuthor() { - return author; - } - - public void setAuthor(String author) { - this.author = author; - } - - public Date getPostTime() { - return postTime; - } - - public void setPostTime(Date postTime) { - this.postTime = postTime; - } - -} diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/composites/TimelinePK.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/composites/TimelinePK.java deleted file mode 100644 index feb5d2913..000000000 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/composites/TimelinePK.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright 2013-2017 the original author or authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.data.cassandra.test.integration.composites; - -import java.io.Serializable; -import java.util.Date; - -import org.springframework.cassandra.core.PrimaryKeyType; -import org.springframework.data.cassandra.mapping.PrimaryKeyClass; -import org.springframework.data.cassandra.mapping.PrimaryKeyColumn; - -/** - * This is an example of the users timeline dynamic table, where all columns are dynamically created by @ColumnId field - * value. The rest fields are places in Cassandra value. Timeline entity is used to store user's status updates that it - * follows in the site. Timeline always ordered by @ColumnId field and we can retrieve last top status updates by using - * limits. - * - * @author Alex Shvid - */ - -@PrimaryKeyClass -public class TimelinePK implements Serializable { - - private static final long serialVersionUID = 1872200498229849025L; - - /* - * Row ID - */ - @PrimaryKeyColumn(ordinal = 0, type = PrimaryKeyType.PARTITIONED) private String username; - - /* - * Clustered Column - */ - @PrimaryKeyColumn(ordinal = 1) private Date time; - - public String getUsername() { - return username; - } - - public void setUsername(String username) { - this.username = username; - } - - public Date getTime() { - return time; - } - - public void setTime(Date time) { - this.time = time; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((time == null) ? 0 : time.hashCode()); - result = prime * result + ((username == null) ? 0 : username.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - TimelinePK other = (TimelinePK) obj; - if (time == null) { - if (other.time != null) - return false; - } else if (!time.equals(other.time)) - return false; - if (username == null) { - if (other.username != null) - return false; - } else if (!username.equals(other.username)) - return false; - return true; - } - -} diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/forcequote/compositeprimarykey/ForceQuotedCompositePrimaryKeyRepositoryTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/forcequote/compositeprimarykey/ForceQuotedCompositePrimaryKeyRepositoryTests.java index e611fa0ae..12c931f83 100755 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/forcequote/compositeprimarykey/ForceQuotedCompositePrimaryKeyRepositoryTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/forcequote/compositeprimarykey/ForceQuotedCompositePrimaryKeyRepositoryTests.java @@ -52,7 +52,7 @@ public class ForceQuotedCompositePrimaryKeyRepositoryTests { assertThat(entity).isSameAs(s); // select - Implicit f = implicitRepository.findOne(key); + Implicit f = implicitRepository.findOne(key).get(); assertThat(entity).isNotSameAs(f); String stringValue = query("stringvalue", "\"Implicit\"", "\"keyZero\"", f.getPrimaryKey().getKeyZero(), "\"keyOne\"", f.getPrimaryKey().getKeyOne()); @@ -62,13 +62,13 @@ public class ForceQuotedCompositePrimaryKeyRepositoryTests { f.setStringValue(f.getStringValue() + "X"); Implicit u = implicitRepository.save(f); assertThat(f).isSameAs(u); - f = implicitRepository.findOne(u.getPrimaryKey()); + f = implicitRepository.findOne(u.getPrimaryKey()).get(); assertThat(u).isNotSameAs(f); assertThat(f.getStringValue()).isEqualTo(u.getStringValue()); // delete implicitRepository.delete(key); - assertThat(implicitRepository.findOne(key)).isNull(); + assertThat(implicitRepository.findOne(key)).isNotPresent(); } public void testExplicit(String tableName, String stringValueColumnName, String keyZeroColumnName, @@ -81,7 +81,7 @@ public class ForceQuotedCompositePrimaryKeyRepositoryTests { assertThat(entity).isSameAs(s); // select - Explicit f = explicitRepository.findOne(key); + Explicit f = explicitRepository.findOne(key).get(); assertThat(entity).isNotSameAs(f); String stringValue = query(stringValueColumnName, tableName, keyZeroColumnName, f.getPrimaryKey().getKeyZero(), keyOneColumnName, f.getPrimaryKey().getKeyOne()); @@ -91,12 +91,12 @@ public class ForceQuotedCompositePrimaryKeyRepositoryTests { f.setStringValue(f.getStringValue() + "X"); Explicit u = explicitRepository.save(f); assertThat(f).isSameAs(u); - f = explicitRepository.findOne(u.getPrimaryKey()); + f = explicitRepository.findOne(u.getPrimaryKey()).get(); assertThat(u).isNotSameAs(f); assertThat(f.getStringValue()).isEqualTo(u.getStringValue()); // delete explicitRepository.delete(key); - assertThat(explicitRepository.findOne(key)).isNull(); + assertThat(explicitRepository.findOne(key)).isNotPresent(); } } diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/forcequote/config/ForceQuotedRepositoryTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/forcequote/config/ForceQuotedRepositoryTests.java index 6f546dd1c..89d677302 100755 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/forcequote/config/ForceQuotedRepositoryTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/forcequote/config/ForceQuotedRepositoryTests.java @@ -48,7 +48,7 @@ public class ForceQuotedRepositoryTests { Implicit s = implicitRepository.save(entity); assertThat(entity).isSameAs(s); - Implicit f = implicitRepository.findOne(key); + Implicit f = implicitRepository.findOne(key).get(); assertThat(entity).isNotSameAs(f); String stringValue = query("stringvalue", "\"Implicit\"", "primarykey", f.getPrimaryKey()); @@ -56,7 +56,7 @@ public class ForceQuotedRepositoryTests { implicitRepository.delete(key); - assertThat(implicitRepository.findOne(key)).isNull(); + assertThat(implicitRepository.findOne(key)).isNotPresent(); } public void testExplicit(String tableName) { @@ -66,7 +66,7 @@ public class ForceQuotedRepositoryTests { Explicit s = explicitRepository.save(entity); assertThat(entity).isSameAs(s); - Explicit f = explicitRepository.findOne(key); + Explicit f = explicitRepository.findOne(key).get(); assertThat(entity).isNotSameAs(f); String stringValue = query("stringvalue", String.format("\"%s\"", tableName), "primarykey", f.getPrimaryKey()); @@ -74,7 +74,7 @@ public class ForceQuotedRepositoryTests { explicitRepository.delete(key); - assertThat(explicitRepository.findOne(key)).isNull(); + assertThat(explicitRepository.findOne(key)).isNotPresent(); } public void testImplicitProperties() { @@ -84,7 +84,7 @@ public class ForceQuotedRepositoryTests { ImplicitProperties s = implicitPropertiesRepository.save(entity); assertThat(entity).isSameAs(s); - ImplicitProperties f = implicitPropertiesRepository.findOne(key); + ImplicitProperties f = implicitPropertiesRepository.findOne(key).get(); assertThat(entity).isNotSameAs(f); String stringValue = query("\"stringValue\"", "implicitproperties", "\"primaryKey\"", f.getPrimaryKey()); @@ -92,7 +92,7 @@ public class ForceQuotedRepositoryTests { implicitPropertiesRepository.delete(key); - assertThat(implicitPropertiesRepository.findOne(key)).isNull(); + assertThat(implicitPropertiesRepository.findOne(key)).isNotPresent(); } public void testExplicitProperties(String stringValueColumnName, String primaryKeyColumnName) { @@ -102,7 +102,7 @@ public class ForceQuotedRepositoryTests { ExplicitProperties s = explicitPropertiesRepository.save(entity); assertThat(entity).isSameAs(s); - ExplicitProperties f = explicitPropertiesRepository.findOne(key); + ExplicitProperties f = explicitPropertiesRepository.findOne(key).get(); assertThat(entity).isNotSameAs(f); String stringValue = query(String.format("\"%s\"", stringValueColumnName), "explicitproperties", @@ -111,6 +111,6 @@ public class ForceQuotedRepositoryTests { implicitPropertiesRepository.delete(key); - assertThat(implicitPropertiesRepository.findOne(key)).isNull(); + assertThat(implicitPropertiesRepository.findOne(key)).isNotPresent(); } } diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/mapping/mapid/repo/RepositoryMapIdIntegrationTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/mapping/mapid/repo/RepositoryMapIdIntegrationTests.java index 2eafee50a..72127e7f3 100755 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/mapping/mapid/repo/RepositoryMapIdIntegrationTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/mapping/mapid/repo/RepositoryMapIdIntegrationTests.java @@ -72,7 +72,7 @@ public class RepositoryMapIdIntegrationTests extends AbstractSpringDataEmbeddedC // select MapId id = id("key", saved.getKey()); - SinglePrimaryKeyColumn selected = singlePrimaryKecColumnRepository.findOne(id); + SinglePrimaryKeyColumn selected = singlePrimaryKecColumnRepository.findOne(id).get(); assertThat(saved).isNotSameAs(selected); assertThat(selected.getKey()).isEqualTo(saved.getKey()); assertThat(selected.getValue()).isEqualTo(saved.getValue()); @@ -82,13 +82,13 @@ public class RepositoryMapIdIntegrationTests extends AbstractSpringDataEmbeddedC SinglePrimaryKeyColumn updated = singlePrimaryKecColumnRepository.save(selected); assertThat(selected).isSameAs(updated); - selected = singlePrimaryKecColumnRepository.findOne(id); + selected = singlePrimaryKecColumnRepository.findOne(id).get(); assertThat(updated).isNotSameAs(selected); assertThat(selected.getValue()).isEqualTo(updated.getValue()); // delete singlePrimaryKecColumnRepository.delete(selected); - assertThat(singlePrimaryKecColumnRepository.findOne(id)).isNull(); + assertThat(singlePrimaryKecColumnRepository.findOne(id)).isEmpty(); } @Test @@ -102,7 +102,7 @@ public class RepositoryMapIdIntegrationTests extends AbstractSpringDataEmbeddedC // select MapId id = id("key0", saved.getKey0()).with("key1", saved.getKey1()); - MultiPrimaryKeyColumns selected = multiPrimaryKeyColumnsRepository.findOne(id); + MultiPrimaryKeyColumns selected = multiPrimaryKeyColumnsRepository.findOne(id).get(); assertThat(saved).isNotSameAs(selected); assertThat(selected.getKey0()).isEqualTo(saved.getKey0()); assertThat(selected.getKey1()).isEqualTo(saved.getKey1()); @@ -113,13 +113,13 @@ public class RepositoryMapIdIntegrationTests extends AbstractSpringDataEmbeddedC MultiPrimaryKeyColumns updated = multiPrimaryKeyColumnsRepository.save(selected); assertThat(selected).isSameAs(updated); - selected = multiPrimaryKeyColumnsRepository.findOne(id); + selected = multiPrimaryKeyColumnsRepository.findOne(id).get(); assertThat(updated).isNotSameAs(selected); assertThat(selected.getValue()).isEqualTo(updated.getValue()); // delete template.delete(selected); - assertThat(multiPrimaryKeyColumnsRepository.findOne(id)).isNull(); + assertThat(multiPrimaryKeyColumnsRepository.findOne(id)).isEmpty(); } } diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/repository/cdi/CdiRepositoryTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/repository/cdi/CdiRepositoryTests.java index 177c4228e..b94ddeed0 100755 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/repository/cdi/CdiRepositoryTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/repository/cdi/CdiRepositoryTests.java @@ -17,6 +17,8 @@ package org.springframework.data.cassandra.test.integration.repository.cdi; import static org.assertj.core.api.Assertions.*; +import java.util.Optional; + import org.apache.webbeans.cditest.CdiTestContainer; import org.apache.webbeans.cditest.CdiTestContainerLoader; import org.junit.AfterClass; @@ -81,21 +83,21 @@ public class CdiRepositoryTests extends AbstractEmbeddedCassandraIntegrationTest assertThat(repository.exists(bean.getUsername())).isTrue(); - User retrieved = repository.findOne(bean.getUsername()); - assertThat(retrieved).isNotNull(); - assertThat(retrieved.getUsername()).isEqualTo(bean.getUsername()); - assertThat(retrieved.getFirstName()).isEqualTo(bean.getFirstName()); - assertThat(retrieved.getLastName()).isEqualTo(bean.getLastName()); + Optional retrieved = repository.findOne(bean.getUsername()); + + assertThat(retrieved).hasValueSatisfying(actual -> { + assertThat(actual.getUsername()).isEqualTo(bean.getUsername()); + assertThat(actual.getFirstName()).isEqualTo(bean.getFirstName()); + assertThat(actual.getLastName()).isEqualTo(bean.getLastName()); + }); assertThat(repository.count()).isEqualTo(1); - assertThat(repository.exists(bean.getUsername())).isTrue(); repository.delete(bean); assertThat(repository.count()).isEqualTo(0); - retrieved = repository.findOne(bean.getUsername()); - assertThat(retrieved).isNull(); + assertThat(repository.findOne(bean.getUsername())).isNotPresent(); } @Test // DATACASS-249 diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/repository/cdi/CdiUserRepository.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/repository/cdi/CdiUserRepository.java index 105807d07..cb9732c59 100644 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/repository/cdi/CdiUserRepository.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/repository/cdi/CdiUserRepository.java @@ -15,14 +15,17 @@ */ package org.springframework.data.cassandra.test.integration.repository.cdi; +import java.util.Optional; + import org.springframework.data.cassandra.test.integration.repository.simple.User; import org.springframework.data.repository.CrudRepository; /** * @author Mohsin Husen * @author Oliver Gierke + * @author Mark Paluch */ public interface CdiUserRepository extends CrudRepository { - User findOne(String id); + Optional findOne(String id); } diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/repository/simple/UserRepositoryIntegrationTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/repository/simple/UserRepositoryIntegrationTests.java index 747ffd9ac..a22c3fc98 100755 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/repository/simple/UserRepositoryIntegrationTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/repository/simple/UserRepositoryIntegrationTests.java @@ -20,6 +20,7 @@ import static org.assertj.core.api.Assertions.*; import java.util.Arrays; import java.util.Collections; import java.util.List; +import java.util.Optional; import org.springframework.data.cassandra.core.CassandraOperations; @@ -112,8 +113,8 @@ public class UserRepositoryIntegrationTests { public void findsUserById() throws Exception { - User user = repository.findOne(tom.getUsername()); - assertThat(user).isNotNull().isEqualTo(tom); + Optional user = repository.findOne(tom.getUsername()); + assertThat(user).isNotNull().contains(tom); } @@ -172,9 +173,12 @@ public class UserRepositoryIntegrationTests { repository.save(tom); - User loadedTom = repository.findOne(tom.getUsername()); + Optional loadedTom = repository.findOne(tom.getUsername()); - assertThat(loadedTom.getPassword()).isNull(); - assertThat(loadedTom.getFriends()).isNull(); + assertThat(loadedTom).hasValueSatisfying(actual -> { + + assertThat(actual.getPassword()).isNull(); + assertThat(actual.getFriends()).isNull(); + }); } } diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/support/SchemaTestUtils.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/support/SchemaTestUtils.java index 52ed03cd4..269df540f 100644 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/support/SchemaTestUtils.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/test/integration/support/SchemaTestUtils.java @@ -44,7 +44,7 @@ public class SchemaTestUtils { public static void potentiallyCreateTableFor(Class entityClass, CassandraOperations operations) { CassandraMappingContext mappingContext = operations.getConverter().getMappingContext(); - CassandraPersistentEntity persistentEntity = mappingContext.getPersistentEntity(entityClass); + CassandraPersistentEntity persistentEntity = mappingContext.getRequiredPersistentEntity(entityClass); operations.getCqlOperations().execute(new SessionCallback() { @Override