DATACASS-389 - Adopt Spring Data Commons changes.
This commit is contained in:
@@ -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<T> extends TableOptionsSpecification<TableSpecification<T>> implements TableDescriptor {
|
||||
|
||||
@@ -60,97 +62,188 @@ public class TableSpecification<T> extends TableOptionsSpecification<TableSpecif
|
||||
|
||||
/**
|
||||
* Adds the given non-key column to the table. Must be specified after all primary 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 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}.
|
||||
*/
|
||||
public T column(String name, DataType type) {
|
||||
return column(cqlId(name), type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the given non-key column to the table. Must be specified after all primary 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}.
|
||||
*/
|
||||
public T column(CqlIdentifier name, DataType type) {
|
||||
return column(name, type, null, null);
|
||||
return column(name, type, Optional.empty(), Optional.empty());
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the given partition key column to the table. Must be specified before any other 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 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 partitionKeyColumn(String name, DataType type) {
|
||||
return partitionKeyColumn(cqlId(name), type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the given partition key column to the table. Must be specified before any other 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 partitionKeyColumn(CqlIdentifier name, DataType type) {
|
||||
return column(name, type, PARTITIONED, null);
|
||||
return column(name, type, Optional.of(PARTITIONED), 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.
|
||||
* @param type The data type of the 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}.
|
||||
* @return this
|
||||
*/
|
||||
public T clusteredKeyColumn(String name, DataType type) {
|
||||
return clusteredKeyColumn(name, type, null);
|
||||
}
|
||||
|
||||
public T clusteredKeyColumn(CqlIdentifier name, DataType type) {
|
||||
return clusteredKeyColumn(name, type, null);
|
||||
return clusteredKeyColumn(cqlId(name), type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the given primary key column to the table with the given ordering (<code>null</code> 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> 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> 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<PrimaryKeyType> optionalKeyType,
|
||||
Optional<Ordering> 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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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<String> 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<String, Object> map = template.queryForMap("SELECT * FROM user;").get();
|
||||
Map<String, Object> 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<String> 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<String, Object> map = template.queryForMap(QueryBuilder.select().from("user")).get();
|
||||
Map<String, Object> 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<String> 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<String> result = new ArrayList<>();
|
||||
template.query(
|
||||
getUninterruptibly(template.query(
|
||||
session -> new GuavaListenableFutureAdapter<PreparedStatement>(
|
||||
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<String, Object> map = template.queryForMap("SELECT * FROM user WHERE id = ?;", "WHITE").get();
|
||||
Map<String, Object> map = getUninterruptibly(template.queryForMap("SELECT * FROM user WHERE id = ?;", "WHITE"));
|
||||
|
||||
assertThat(map).containsEntry("id", "WHITE").containsEntry("username", "Walter");
|
||||
}
|
||||
|
||||
private static <T> T getUninterruptibly(Future<T> future) {
|
||||
|
||||
try {
|
||||
return future.get();
|
||||
} catch (Exception e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 <T> Optional<T> getPropertyValue(CassandraPersistentProperty property) {
|
||||
|
||||
String expression = property.getSpelExpression();
|
||||
if (expression != null) {
|
||||
return evaluator.evaluate(expression);
|
||||
Optional<String> 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)
|
||||
|
||||
@@ -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);
|
||||
<T> Optional<Object> convertToCassandraColumn(Optional<T> obj, TypeInformation<?> typeInformation);
|
||||
|
||||
/**
|
||||
* Returns the {@link CustomConversions} registered in the {@link CassandraConverter}.
|
||||
|
||||
@@ -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<CassandraPersistentProperty> {
|
||||
|
||||
public CassandraPersistentEntityParameterValueProvider(PersistentEntity<?, CassandraPersistentProperty> entity,
|
||||
PropertyValueProvider<CassandraPersistentProperty> provider, Object parent) {
|
||||
super(entity, provider, parent);
|
||||
}
|
||||
}
|
||||
@@ -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 <T> Optional<T> getPropertyValue(CassandraPersistentProperty property) {
|
||||
|
||||
String expression = property.getSpelExpression();
|
||||
|
||||
if (expression != null) {
|
||||
return evaluator.evaluate(expression);
|
||||
Optional<String> 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)
|
||||
|
||||
@@ -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<ConvertiblePair> readingPairs;
|
||||
private final Set<ConvertiblePair> writingPairs;
|
||||
private final Set<Class<?>> customSimpleTypes;
|
||||
private final CassandraSimpleTypeHolder simpleTypeHolder;
|
||||
|
||||
private final List<Object> converters;
|
||||
|
||||
private final Map<ConvertiblePair, CacheValue<Class<?>>> customReadTargetTypes;
|
||||
private final Map<ConvertiblePair, CacheValue<Class<?>>> customWriteTargetTypes;
|
||||
private final Map<Class<?>, CacheValue<Class<?>>> rawWriteTargetTypes;
|
||||
private final Map<ConvertiblePair, Class<?>> customReadTargetTypes;
|
||||
private final Map<ConvertiblePair, Class<?>> customWriteTargetTypes;
|
||||
private final Map<Class<?>, Class<?>> rawWriteTargetTypes;
|
||||
|
||||
/**
|
||||
* Creates an empty {@link CustomConversions} object.
|
||||
*/
|
||||
CustomConversions() {
|
||||
this(new ArrayList<Object>());
|
||||
this(new ArrayList<>());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -85,12 +83,11 @@ public class CustomConversions {
|
||||
|
||||
Assert.notNull(converters, "List of converters must not be null");
|
||||
|
||||
this.readingPairs = new LinkedHashSet<ConvertiblePair>();
|
||||
this.writingPairs = new LinkedHashSet<ConvertiblePair>();
|
||||
this.customSimpleTypes = new HashSet<Class<?>>();
|
||||
this.customReadTargetTypes = new ConcurrentHashMap<ConvertiblePair, CacheValue<Class<?>>>();
|
||||
this.customWriteTargetTypes = new ConcurrentHashMap<ConvertiblePair, CacheValue<Class<?>>>();
|
||||
this.rawWriteTargetTypes = new ConcurrentHashMap<Class<?>, CacheValue<Class<?>>>();
|
||||
this.readingPairs = new LinkedHashSet<>();
|
||||
this.writingPairs = new LinkedHashSet<>();
|
||||
this.customReadTargetTypes = new ConcurrentHashMap<>();
|
||||
this.customWriteTargetTypes = new ConcurrentHashMap<>();
|
||||
this.rawWriteTargetTypes = new ConcurrentHashMap<>();
|
||||
|
||||
List<Object> toRegister = new ArrayList<Object>();
|
||||
|
||||
@@ -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<Class<?>>() {
|
||||
|
||||
@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 <T> Class<?> getOrCreateAndCache(T key, Map<T, CacheValue<Class<?>>> cache, Producer producer) {
|
||||
|
||||
CacheValue<Class<?>> cacheValue = cache.get(key);
|
||||
|
||||
if (cacheValue != null) {
|
||||
return cacheValue.getValue();
|
||||
}
|
||||
|
||||
Class<?> type = producer.get();
|
||||
|
||||
cache.put(key, CacheValue.<Class<?>> ofNullable(type));
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
private interface Producer {
|
||||
Class<?> get();
|
||||
private static <T> Class<?> getOrCreateAndCache(T key, Map<T, Class<?>> cache, Supplier<Class<?>> producer) {
|
||||
return cache.computeIfAbsent(key, t -> producer.get());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<R> persistentEntity = (CassandraPersistentEntity<R>) 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<CassandraPersistentProperty> 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<CassandraPersistentProperty> 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<CassandraPersistentProperty>() {
|
||||
|
||||
@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<Object> 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<CassandraPersistentProperty> 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 <T> Optional<Object> convertToCassandraColumn(Optional<T> 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<CassandraPersistentProperty>() {
|
||||
entity.getPersistentProperties().forEach(property -> {
|
||||
|
||||
@Override
|
||||
public void doWithPersistentProperty(CassandraPersistentProperty property) {
|
||||
Optional<Object> 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<CassandraPersistentProperty>() {
|
||||
entity.getPersistentProperties().forEach(property -> {
|
||||
|
||||
@Override
|
||||
public void doWithPersistentProperty(CassandraPersistentProperty property) {
|
||||
Optional<Object> 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<Clause> 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<Clause> 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<CassandraPersistentProperty>() {
|
||||
entity.getPersistentProperties().forEach(property -> {
|
||||
|
||||
@Override
|
||||
public void doWithPersistentProperty(CassandraPersistentProperty property) {
|
||||
Optional<Object> 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<Object> 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<Object> 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<CassandraPersistentProperty> optionalIdProperty = entity.getIdProperty();
|
||||
|
||||
Optional<CassandraPersistentProperty> 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<Object>) 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<Clause> clauses = new ArrayList<Clause>();
|
||||
Collection<Clause> clauses = new ArrayList<>();
|
||||
|
||||
entity.doWithProperties(new PropertyHandler<CassandraPersistentProperty>() {
|
||||
|
||||
@Override
|
||||
public void doWithPersistentProperty(CassandraPersistentProperty property) {
|
||||
TypeCodec<Object> codec = getCodec(property);
|
||||
Object value = accessor.getProperty(property, codec.getJavaType().getRawType());
|
||||
clauses.add(QueryBuilder.eq(property.getColumnName().toCql(), value));
|
||||
}
|
||||
entity.getPersistentProperties().forEach(property -> {
|
||||
TypeCodec<Object> codec = getCodec(property);
|
||||
Optional<Object> 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<Clause> clauses = new ArrayList<Clause>();
|
||||
Collection<Clause> clauses = new ArrayList<>();
|
||||
|
||||
for (Entry<String, Serializable> 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<CassandraPersistentProperty> 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<Object> 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<CassandraPersistentProperty> optionalIdProperty = entity.getIdProperty();
|
||||
|
||||
if (idProperty != null) {
|
||||
return accessor.getProperty(idProperty,
|
||||
idProperty.isCompositePrimaryKey() ? (Class<Object>) idProperty.getType()
|
||||
: (Class<Object>) getTargetType(idProperty));
|
||||
if (optionalIdProperty.isPresent()) {
|
||||
// TODO: NullId
|
||||
CassandraPersistentProperty idProperty = optionalIdProperty.get();
|
||||
return accessor.getProperty(idProperty, idProperty.isCompositePrimaryKey() ? (Class<Object>) idProperty.getType()
|
||||
: (Class<Object>) 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<CassandraPersistentProperty>() {
|
||||
|
||||
@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 <T> Optional<T> getWriteValue(CassandraPersistentProperty property, ConvertingPropertyAccessor accessor) {
|
||||
return getWriteValue(accessor.getProperty(property, (Class<T>) 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 <I, O> Optional<O> getWriteValue(Optional<I> 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<O>) typeInformation.getType());
|
||||
}
|
||||
|
||||
if (getCustomConversions().hasCustomWriteTarget(value.getClass())) {
|
||||
return getConversionService().convert(value, getCustomConversions().getCustomWriteTarget(value.getClass()));
|
||||
|
||||
return Optional.ofNullable(getConversionService().convert(value,
|
||||
(Class<O>) getCustomConversions().getCustomWriteTarget(value.getClass())));
|
||||
}
|
||||
|
||||
TypeInformation<?> type = (typeInformation != null ? typeInformation : ClassTypeInformation.from(value.getClass()));
|
||||
@@ -702,58 +682,65 @@ public class MappingCassandraConverter extends AbstractCassandraConverter
|
||||
Collection<Object> 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<CassandraPersistentEntity<?>> 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<O>) 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 <I, O> Optional<O> getPotentiallyConvertedSimpleValue(Optional<I> optionalValue,
|
||||
Class<O> 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<O>) optionalValue;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -812,18 +799,22 @@ public class MappingCassandraConverter extends AbstractCassandraConverter
|
||||
* @return the return value, may be {@literal null}.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
private Object getReadValue(PropertyValueProvider<CassandraPersistentProperty> row,
|
||||
private <T> Optional<T> getReadValue(PropertyValueProvider<CassandraPersistentProperty> row,
|
||||
CassandraPersistentProperty property) {
|
||||
|
||||
Object obj = row.getPropertyValue(property);
|
||||
Optional<Object> 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<Object> original = (Collection<Object>) obj;
|
||||
return obj.map(it -> {
|
||||
|
||||
Collection<Object> original = (Collection<Object>) it;
|
||||
|
||||
Collection<Object> 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<CassandraPersistentEntity<?>> 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<TypeInformation<?>> componentType = targetType.getComponentType();
|
||||
Class<?> rawComponentType = componentType.map(TypeInformation::getType).orElse((Class) List.class);
|
||||
|
||||
collectionType = Collection.class.isAssignableFrom(collectionType) ? collectionType : List.class;
|
||||
Collection<Object> items = targetType.getType().isArray() ? new ArrayList<Object>()
|
||||
@@ -875,13 +869,17 @@ public class MappingCassandraConverter extends AbstractCassandraConverter
|
||||
return getPotentiallyConvertedSimpleRead(items, collectionType);
|
||||
}
|
||||
|
||||
CassandraPersistentEntity<?> persistentEntity = getMappingContext().getPersistentEntity(componentType);
|
||||
Optional<CassandraPersistentEntity<?>> 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 <T> Optional<T> getPropertyValue(CassandraPersistentProperty property) {
|
||||
return getReadValue(parent, property);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 <T> ListenableFuture<T> selectOne(Statement statement, Class<T> 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 <T> CassandraPersistentEntity<?> getPersistentEntity(Class<T> 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<T, S>
|
||||
|
||||
@@ -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<TableMetadata> getTableMetadata(String keyspace, CqlIdentifier tableName);
|
||||
|
||||
/**
|
||||
* Returns {@link KeyspaceMetadata} for the current keyspace.
|
||||
|
||||
@@ -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<String, Object> 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<TableMetadata> 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<TableMetadata>) session -> session.getCluster().getMetadata()
|
||||
.getKeyspace(keyspace).getTable(tableName.toCql()));
|
||||
return Optional.ofNullable(getCqlOperations().execute((SessionCallback<TableMetadata>) 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<KeyspaceMetadata>() {
|
||||
return getCqlOperations().execute((SessionCallback<KeyspaceMetadata>) 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;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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<CreateUserTypeSpecification> specifications = new ArrayList<>();
|
||||
|
||||
Set<CqlIdentifier> created = new HashSet<>();
|
||||
|
||||
for (CassandraPersistentEntity<?> entity : entities) {
|
||||
entities.forEach(entity -> {
|
||||
|
||||
Set<CqlIdentifier> 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<CqlIdentifier> seen) {
|
||||
|
||||
entity.doWithProperties(new PropertyHandler<CassandraPersistentProperty>() {
|
||||
|
||||
@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);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<T> 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 <T> CassandraPersistentEntity<?> getPersistentEntity(Class<T> 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();
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -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 <T> CassandraPersistentEntity<?> getPersistentEntity(Class<T> 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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<Class<?>, CassandraPersistentEntity<?>> entitiesByType = new HashMap<Class<?>, CassandraPersistentEntity<?>>();
|
||||
protected Map<CqlIdentifier, Set<CassandraPersistentEntity<?>>> entitySetsByTableName = new HashMap<CqlIdentifier, Set<CassandraPersistentEntity<?>>>();
|
||||
protected Map<Class<?>, CassandraPersistentEntity<?>> entitiesByType = new HashMap<>();
|
||||
protected Map<CqlIdentifier, Set<CassandraPersistentEntity<?>>> entitySetsByTableName = new HashMap<>();
|
||||
|
||||
protected Set<CassandraPersistentEntity<?>> primaryKeyEntities = new HashSet<CassandraPersistentEntity<?>>();
|
||||
protected Set<CassandraPersistentEntity<?>> userDefinedTypes = new HashSet<CassandraPersistentEntity<?>>();
|
||||
protected Set<CassandraPersistentEntity<?>> tableEntities = new HashSet<CassandraPersistentEntity<?>>();
|
||||
protected Set<CassandraPersistentEntity<?>> primaryKeyEntities = new HashSet<>();
|
||||
protected Set<CassandraPersistentEntity<?>> userDefinedTypes = new HashSet<>();
|
||||
protected Set<CassandraPersistentEntity<?>> 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<CassandraPersistentEntity<?>> entities = entitySetsByTableName.get(entity.getTableName());
|
||||
|
||||
if (entities == null) {
|
||||
entities = new HashSet<CassandraPersistentEntity<?>>();
|
||||
entitySetsByTableName.put(entity.getTableName(), entities);
|
||||
}
|
||||
Set<CassandraPersistentEntity<?>> 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<CassandraPersistentProperty>() {
|
||||
|
||||
@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<CassandraPersistentProperty>() {
|
||||
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<CassandraPersistentProperty>() {
|
||||
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<CassandraPersistentEntity<?>> 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<CassandraPersistentEntity<?>> 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())) {
|
||||
|
||||
@@ -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<T> extends BasicPersistentEntity<T,
|
||||
|
||||
protected static final CassandraPersistentEntityMetadataVerifier DEFAULT_VERIFIER = new CompositeCassandraPersistentEntityMetadataVerifier();
|
||||
|
||||
private static final Optional<Comparator<CassandraPersistentProperty>> PROPERTY_COMPARATOR = Optional
|
||||
.of(CassandraPersistentPropertyComparator.INSTANCE);
|
||||
|
||||
protected ApplicationContext context;
|
||||
|
||||
protected Boolean forceQuote;
|
||||
protected Optional<Boolean> forceQuote = Optional.empty();
|
||||
|
||||
protected CassandraMappingContext mappingContext;
|
||||
|
||||
protected CassandraPersistentEntityMetadataVerifier verifier = DEFAULT_VERIFIER;
|
||||
|
||||
protected CqlIdentifier tableName;
|
||||
protected Optional<CqlIdentifier> tableName = Optional.empty();
|
||||
|
||||
protected StandardEvaluationContext spelContext;
|
||||
|
||||
@@ -93,7 +97,8 @@ public class BasicCassandraPersistentEntity<T> extends BasicPersistentEntity<T,
|
||||
public BasicCassandraPersistentEntity(TypeInformation<T> 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<T> extends BasicPersistentEntity<T,
|
||||
|
||||
protected CqlIdentifier determineTableName() {
|
||||
|
||||
Table tableAnnotation = findAnnotation(Table.class);
|
||||
Optional<Table> 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<T> extends BasicPersistentEntity<T,
|
||||
*/
|
||||
@Override
|
||||
public boolean isCompositePrimaryKey() {
|
||||
return (findAnnotation(PrimaryKeyClass.class) != null);
|
||||
return findAnnotation(PrimaryKeyClass.class).isPresent();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
@@ -151,16 +157,14 @@ public class BasicCassandraPersistentEntity<T> extends BasicPersistentEntity<T,
|
||||
protected void addCompositePrimaryKeyProperties(CassandraPersistentEntity<?> compositePrimaryKeyEntity,
|
||||
final List<CassandraPersistentProperty> properties) {
|
||||
|
||||
compositePrimaryKeyEntity.doWithProperties(new PropertyHandler<CassandraPersistentProperty>() {
|
||||
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<T> extends BasicPersistentEntity<T,
|
||||
if (verifier != null) {
|
||||
verifier.verify(this);
|
||||
}
|
||||
|
||||
if (!tableName.isPresent()) {
|
||||
setTableName(determineTableName());
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
@@ -204,9 +212,13 @@ public class BasicCassandraPersistentEntity<T> extends BasicPersistentEntity<T,
|
||||
*/
|
||||
@Override
|
||||
public void setForceQuote(boolean forceQuote) {
|
||||
if (this.forceQuote == null || this.forceQuote != forceQuote) {
|
||||
this.forceQuote = forceQuote;
|
||||
setTableName(cqlId(tableName.getUnquoted(), forceQuote));
|
||||
|
||||
boolean changed = !this.forceQuote.isPresent() || this.forceQuote.filter(v -> v != forceQuote).isPresent();
|
||||
|
||||
this.forceQuote = Optional.of(forceQuote);
|
||||
|
||||
if (changed) {
|
||||
setTableName(cqlId(getTableName().getUnquoted(), forceQuote));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -225,7 +237,7 @@ public class BasicCassandraPersistentEntity<T> extends BasicPersistentEntity<T,
|
||||
public void setTableName(CqlIdentifier tableName) {
|
||||
|
||||
Assert.notNull(tableName, "CqlIdentifier must not be null");
|
||||
this.tableName = tableName;
|
||||
this.tableName = Optional.of(tableName);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
@@ -233,8 +245,7 @@ public class BasicCassandraPersistentEntity<T> extends BasicPersistentEntity<T,
|
||||
*/
|
||||
@Override
|
||||
public CqlIdentifier getTableName() {
|
||||
tableName = (tableName != null ? tableName : determineTableName());
|
||||
return tableName;
|
||||
return tableName.orElseGet(this::determineTableName);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -15,12 +15,10 @@
|
||||
*/
|
||||
package org.springframework.data.cassandra.mapping;
|
||||
|
||||
import java.io.Serializable;
|
||||
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;
|
||||
|
||||
/**
|
||||
@@ -46,15 +44,15 @@ public class BasicCassandraPersistentEntityMetadataVerifier implements Cassandra
|
||||
@Override
|
||||
public void verify(CassandraPersistentEntity<?> entity) throws MappingException {
|
||||
|
||||
if (entity.getType().isInterface() || entity.findAnnotation(Table.class) == null) {
|
||||
if (entity.getType().isInterface() || !entity.findAnnotation(Table.class).isPresent()) {
|
||||
return;
|
||||
}
|
||||
|
||||
List<MappingException> exceptions = new ArrayList<MappingException>();
|
||||
List<MappingException> exceptions = new ArrayList<>();
|
||||
|
||||
final List<CassandraPersistentProperty> idProperties = new ArrayList<CassandraPersistentProperty>();
|
||||
final List<CassandraPersistentProperty> partitionKeyColumns = new ArrayList<CassandraPersistentProperty>();
|
||||
final List<CassandraPersistentProperty> primaryKeyColumns = new ArrayList<CassandraPersistentProperty>();
|
||||
final List<CassandraPersistentProperty> idProperties = new ArrayList<>();
|
||||
final List<CassandraPersistentProperty> partitionKeyColumns = new ArrayList<>();
|
||||
final List<CassandraPersistentProperty> 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<CassandraPersistentProperty>() {
|
||||
|
||||
@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
|
||||
|
||||
@@ -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<Ordering> 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> 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<CassandraPersistentEntity<?>> optionalEntity = getOwner().getMappingContext()
|
||||
.getPersistentEntity(javaType);
|
||||
|
||||
if (persistentEntity != null && persistentEntity.isUserDefinedType()) {
|
||||
return persistentEntity.getUserType();
|
||||
Optional<CassandraPersistentEntity<?>> 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<PrimaryKey> 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<PrimaryKeyColumn> 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<Column> 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<CqlIdentifier> columnNames) {
|
||||
|
||||
compositePrimaryKeyEntity.doWithProperties(new PropertyHandler<CassandraPersistentProperty>() {
|
||||
|
||||
@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<CassandraPersistentProperty> getAssociation() {
|
||||
throw new UnsupportedOperationException("Cassandra does not support associations");
|
||||
public Optional<Association<CassandraPersistentProperty>> getAssociation() {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
|
||||
@@ -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<T>
|
||||
extends MutablePersistentEntity<T, CassandraPersistentProperty>, ApplicationContextAware {
|
||||
|
||||
@@ -39,6 +41,7 @@ public interface CassandraPersistentEntity<T>
|
||||
*/
|
||||
boolean isCompositePrimaryKey();
|
||||
|
||||
// TODO: return rather a Stream, rename to "getPrimaryKeyProperties"
|
||||
List<CassandraPersistentProperty> getCompositePrimaryKeyProperties();
|
||||
|
||||
/**
|
||||
@@ -46,12 +49,18 @@ public interface CassandraPersistentEntity<T>
|
||||
*/
|
||||
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<T>
|
||||
* @see UserDefinedType
|
||||
*/
|
||||
UserType getUserType();
|
||||
|
||||
// TODO: Review if that's required or it can be handled in a different way
|
||||
CassandraMappingContext getMappingContext();
|
||||
|
||||
ApplicationContext getApplicationContext();
|
||||
}
|
||||
|
||||
@@ -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<Ordering> getPrimaryKeyOrdering();
|
||||
|
||||
/**
|
||||
* The column's data type. Not valid for a composite primary key.
|
||||
|
||||
@@ -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<Cassandr
|
||||
boolean rightIsPrimaryKey = right.isPrimaryKeyColumn();
|
||||
|
||||
if (leftIsPrimaryKey && rightIsPrimaryKey) {
|
||||
return CassandraPrimaryKeyColumnAnnotationComparator.INSTANCE.compare(left.findAnnotation(PrimaryKeyColumn.class),
|
||||
right.findAnnotation(PrimaryKeyColumn.class));
|
||||
|
||||
Optional<PrimaryKeyColumn> optionalLeftAnnotation = left.findAnnotation(PrimaryKeyColumn.class);
|
||||
Optional<PrimaryKeyColumn> 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;
|
||||
|
||||
@@ -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<T> extends BasicCassandraPersiste
|
||||
*/
|
||||
@Override
|
||||
protected CqlIdentifier determineTableName() {
|
||||
UserDefinedType typeAnnotation = findAnnotation(UserDefinedType.class);
|
||||
return determineName(typeAnnotation.value(), typeAnnotation.forceQuote());
|
||||
|
||||
Optional<UserDefinedType> typeAnnotation = findAnnotation(UserDefinedType.class);
|
||||
return typeAnnotation.map(userDefinedType -> determineName(userDefinedType.value(), userDefinedType.forceQuote()))
|
||||
.orElseGet(super::determineDefaultName);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
|
||||
@@ -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<CassandraPersistentProperty>() {
|
||||
|
||||
@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
|
||||
|
||||
@@ -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<T> extends CdiRepositoryBean<T> {
|
||||
* @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<CassandraOperations> operations, Set<Annotation> qualifiers,
|
||||
Class<T> repositoryType, BeanManager beanManager, CustomRepositoryImplementationDetector detector) {
|
||||
Class<T> repositoryType, BeanManager beanManager, Optional<CustomRepositoryImplementationDetector> detector) {
|
||||
super(qualifiers, repositoryType, beanManager, detector);
|
||||
|
||||
Assert.notNull(operations, "Cannot create repository with 'null' for CassandraOperations.");
|
||||
@@ -58,12 +59,19 @@ public class CassandraRepositoryBean<T> extends CdiRepositoryBean<T> {
|
||||
|
||||
/*
|
||||
* (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<T> creationalContext, Class<T> repositoryType, Object customImplementation) {
|
||||
protected T create(CreationalContext<T> creationalContext, Class<T> repositoryType,
|
||||
Optional<Object> 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
|
||||
|
||||
@@ -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 <T> CdiRepositoryBean<T> createRepositoryBean(Class<T> repositoryType, Set<Annotation> qualifiers,
|
||||
BeanManager beanManager) {
|
||||
|
||||
Bean<CassandraOperations> 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<CassandraOperations> 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<T>(cassandraOperationsBean, qualifiers, repositoryType, beanManager,
|
||||
getCustomImplementationDetector());
|
||||
Optional.of(getCustomImplementationDetector()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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<Object>) execute(accessor))
|
||||
return (getQueryMethod().isCollectionQuery() ? Flux.defer(() -> (Publisher<Object>) execute(accessor))
|
||||
: Mono.defer(() -> (Mono<Object>) 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);
|
||||
}
|
||||
|
||||
@@ -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<Select, Clause> {
|
||||
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<Select, Clause> {
|
||||
@Override
|
||||
protected Clause create(Part part, Iterator<Object> iterator) {
|
||||
|
||||
PersistentPropertyPath<CassandraPersistentProperty> path =
|
||||
mappingContext.getPersistentPropertyPath(part.getProperty());
|
||||
PersistentPropertyPath<CassandraPersistentProperty> path = mappingContext
|
||||
.getPersistentPropertyPath(part.getProperty());
|
||||
|
||||
CassandraPersistentProperty property = path.getLeafProperty();
|
||||
|
||||
@@ -175,8 +176,8 @@ class CassandraQueryCreator extends AbstractQueryCreator<Select, Clause> {
|
||||
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<Select, Clause> {
|
||||
* 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<Select, Clause> {
|
||||
return select;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static CassandraPersistentProperty getPersistentProperty(CassandraPersistentEntity<?> entity,
|
||||
String dotPath) {
|
||||
|
||||
String[] segments = PUNCTUATION_PATTERN.split(dotPath);
|
||||
|
||||
CassandraPersistentProperty property = null;
|
||||
Optional<CassandraPersistentProperty> 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()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
|
||||
@@ -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<Object>((Class<Object>) 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<CassandraPersistentEntity<?>> 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<Object>((Class<Object>) returnedEntity.getType(),
|
||||
collectionEntity);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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<Class<?>> 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<Object> 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<Object> 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<CassandraPersistentProperty> 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<CassandraPersistentProperty> 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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<Object, Object> {
|
||||
|
||||
private final Class<?> targetType;
|
||||
|
||||
private final MappingContext<? extends PersistentEntity<?, ?>, ? extends PersistentProperty<?>> context;
|
||||
private final EntityInstantiator instantiator;
|
||||
|
||||
private final Optional<EntityInstantiator> instantiator;
|
||||
|
||||
/**
|
||||
* Create a new {@link Converter} to instantiate DTOs.
|
||||
@@ -58,7 +62,8 @@ class DtoInstantiatingConverter implements Converter<Object, Object> {
|
||||
|
||||
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<Object, Object> {
|
||||
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<Object> 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<?, ? extends PersistentProperty<?>> constructor =
|
||||
targetEntity.getPersistenceConstructor();
|
||||
|
||||
targetEntity.doWithProperties(new SimplePropertyHandler() {
|
||||
Optional<? extends PreferredConstructor<?, ? extends PersistentProperty<?>>> 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;
|
||||
|
||||
@@ -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<ParameterBinding> bindings) {
|
||||
|
||||
|
||||
@@ -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 <T, ID extends Serializable> CassandraEntityInformation<T, ID> getEntityInformation(Class<T> 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<T, ID>((CassandraPersistentEntity<T>) 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<QueryLookupStrategy> 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;
|
||||
|
||||
@@ -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<T, ID extends Serializable> exten
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public ID getId(T entity) {
|
||||
public Optional<ID> getId(T entity) {
|
||||
|
||||
Assert.notNull(entity, "Entity must not be null");
|
||||
|
||||
CassandraPersistentProperty idProperty = entityMetadata.getIdProperty();
|
||||
Optional<CassandraPersistentProperty> 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<T, ID extends Serializable> exten
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public Class<ID> getIdType() {
|
||||
return (Class<ID>) (entityMetadata.getIdProperty() == null ? MapId.class
|
||||
: entityMetadata.getIdProperty().getType());
|
||||
return entityMetadata.getIdProperty().map(p -> (Class<ID>) p.getType()).orElse((Class<ID>) MapId.class);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
|
||||
@@ -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<QueryLookupStrategy> 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 <T, ID extends Serializable> CassandraEntityInformation<T, ID> getEntityInformation(Class<T> 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<T>) entity, operations.getConverter());
|
||||
}
|
||||
|
||||
@@ -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<T, ID extends Serializable> implements Ty
|
||||
for (S entity : entities) {
|
||||
|
||||
S saved;
|
||||
|
||||
if (entityInformation.isNew(entity)) {
|
||||
saved = operations.insert(entity);
|
||||
} else {
|
||||
@@ -132,11 +134,11 @@ public class SimpleCassandraRepository<T, ID extends Serializable> implements Ty
|
||||
* @see org.springframework.data.repository.CrudRepository#findOne(java.io.Serializable)
|
||||
*/
|
||||
@Override
|
||||
public T findOne(ID id) {
|
||||
public Optional<T> 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<T, ID extends Serializable> 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)
|
||||
|
||||
@@ -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<String>());
|
||||
|
||||
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<String>());
|
||||
|
||||
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<String, String>());
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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<Person> 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<Long> 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();
|
||||
|
||||
@@ -157,7 +157,8 @@ public class AsyncCassandraTemplateUnitTests {
|
||||
when(row.getObject(1)).thenReturn("Walter");
|
||||
when(row.getObject(2)).thenReturn("White");
|
||||
|
||||
ListenableFuture<Person> future = template.selectOne("SELECT * FROM person WHERE id='myid';", Person.class);
|
||||
ListenableFuture<Person> 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());
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -49,7 +49,7 @@ import com.datastax.driver.core.querybuilder.Batch;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link CassandraTemplate}.
|
||||
*
|
||||
*
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
|
||||
@@ -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<CassandraPersistentProperty> idProperty = persistentEntity.getIdProperty();
|
||||
|
||||
assertThat(idProperty.getColumnName().toCql()).isEqualTo("foo");
|
||||
assertThat(idProperty).hasValueSatisfying(actual -> {
|
||||
|
||||
List<CqlIdentifier> columnNames = idProperty.getColumnNames();
|
||||
assertThat(actual.getColumnName().toCql()).isEqualTo("foo");
|
||||
|
||||
assertThat(columnNames).hasSize(1);
|
||||
assertThat(columnNames.get(0).toCql()).isEqualTo("foo");
|
||||
List<CqlIdentifier> 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]");
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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<CassandraPersistentProperty>();
|
||||
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<CassandraPersistentProperty> actual = new LinkedList<CassandraPersistentProperty>();
|
||||
|
||||
@@ -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<CassandraPersistentProperty>();
|
||||
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<CassandraPersistentProperty> actual = new LinkedList<CassandraPersistentProperty>();
|
||||
|
||||
|
||||
@@ -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<Message> entitySpy = spy(
|
||||
new BasicCassandraPersistentEntity<Message>(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<Message> entitySpy = spy(
|
||||
new BasicCassandraPersistentEntity<Message>(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));
|
||||
}
|
||||
|
||||
@@ -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 <T> BasicCassandraPersistentEntity<T> getEntity(Class<T> type) {
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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<CqlIdentifier> 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<CqlIdentifier> names = Arrays.asList(new CqlIdentifier[] { cqlId("stringZero"), cqlId("stringOne") });
|
||||
CassandraPersistentEntity<?> entity = context.getPersistentEntity(DefaultComposite.class);
|
||||
List<CqlIdentifier> 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<CqlIdentifier> 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
|
||||
|
||||
@@ -143,7 +143,7 @@ public class PrimaryKeyClassEntityMetadataVerifierUnitTests {
|
||||
}
|
||||
|
||||
private CassandraPersistentEntity<?> getEntity(Class<?> entityClass) {
|
||||
return context.getPersistentEntity(entityClass);
|
||||
return context.getRequiredPersistentEntity(entityClass);
|
||||
}
|
||||
|
||||
interface MyInterface {
|
||||
|
||||
@@ -275,8 +275,8 @@ public class CassandraQueryCreatorUnitTests {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private <T> CassandraEntityInformation<T, Serializable> getEntityInformation(final Class<T> entityClass) {
|
||||
return new MappingCassandraEntityInformation<T, Serializable>(
|
||||
(CassandraPersistentEntity) context.getPersistentEntity(entityClass), converter);
|
||||
return new MappingCassandraEntityInformation<>(
|
||||
(CassandraPersistentEntity) context.getRequiredPersistentEntity(entityClass), converter);
|
||||
}
|
||||
|
||||
@Table
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<Class<?>> getDynamicProjection() {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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> 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> 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<Person> 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<Person> 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<Person> persistentDave = repository.findOne(dave.getId());
|
||||
assertThat(persistentDave).contains(dave);
|
||||
|
||||
Person persistentHomer = repository.findOne(person.getId());
|
||||
assertThat(persistentHomer).isEqualTo(person);
|
||||
Optional<Person> 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<Person> 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<Person> 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<Person> loaded = repository.findOne(boyd.getId());
|
||||
|
||||
assertThat(loaded).isNull();
|
||||
assertThat(loaded).isPresent();
|
||||
}
|
||||
|
||||
interface PersonRepostitory extends TypedIdCassandraRepository<Person, String> {}
|
||||
|
||||
@@ -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");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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<Comment, CommentKey> {}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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<String> resources;
|
||||
private Map<Date, String> comments;
|
||||
private Set<String> likes;
|
||||
private Set<String> 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<String> getResources() {
|
||||
return resources;
|
||||
}
|
||||
|
||||
public void setResources(Set<String> resources) {
|
||||
this.resources = resources;
|
||||
}
|
||||
|
||||
public Map<Date, String> getComments() {
|
||||
return comments;
|
||||
}
|
||||
|
||||
public void setComments(Map<Date, String> comments) {
|
||||
this.comments = comments;
|
||||
}
|
||||
|
||||
public Set<String> getLikes() {
|
||||
return likes;
|
||||
}
|
||||
|
||||
public void setLikes(Set<String> likes) {
|
||||
this.likes = likes;
|
||||
}
|
||||
|
||||
public Set<String> getFollowers() {
|
||||
return followers;
|
||||
}
|
||||
|
||||
public void setFollowers(Set<String> followers) {
|
||||
this.followers = followers;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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<User> 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
|
||||
|
||||
@@ -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, String> {
|
||||
|
||||
User findOne(String id);
|
||||
Optional<User> findOne(String id);
|
||||
}
|
||||
|
||||
@@ -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> 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<User> 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();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<Object>() {
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user