DATACASS-466 - Align insert(…) and update(…) return types to their possible outcomes.
We now return WriteResult for insert(…) and update(…) methods accepting WriteOptions. Conditional writes return a state whether the operation was applied or not and this result is propagated via WriteResult to the caller. Synchronous insert(…) and update(…) without WriteOptions methods do not return a value and are consistent with other Template API modules. The absence of an Exception indicates success. Asynchronous and reactive insert(…) and update(…) without WriteOptions continue to return the entity to make the entity accessible after operation completion. Previously, we returned null if a lightweight transaction was not applied or suppressed the value value emission.
This commit is contained in:
@@ -237,11 +237,10 @@ public interface AsyncCassandraOperations {
|
||||
*
|
||||
* @param entity The entity to insert, must not be {@literal null}.
|
||||
* @param options may be {@literal null}.
|
||||
* @return the inserted entity or a {@literal null} inside of {@link ListenableFuture} if the {@code INSERT} operation
|
||||
* was not applied.
|
||||
* @return the {@link WriteResult} for this operation.
|
||||
* @throws DataAccessException if there is any problem executing the query.
|
||||
*/
|
||||
<T> ListenableFuture<T> insert(T entity, InsertOptions options) throws DataAccessException;
|
||||
ListenableFuture<WriteResult> insert(Object entity, InsertOptions options) throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Update the given entity and return the entity if the update was applied.
|
||||
@@ -257,11 +256,10 @@ public interface AsyncCassandraOperations {
|
||||
*
|
||||
* @param entity The entity to update, must not be {@literal null}.
|
||||
* @param options may be {@literal null}.
|
||||
* @return the updated entity or a {@literal null} inside of {@link ListenableFuture}
|
||||
* if the {@code UPDATE} operation was not applied.
|
||||
* @return the {@link WriteResult} for this operation.
|
||||
* @throws DataAccessException if there is any problem executing the query.
|
||||
*/
|
||||
<T> ListenableFuture<T> update(T entity, UpdateOptions options) throws DataAccessException;
|
||||
ListenableFuture<WriteResult> update(Object entity, UpdateOptions options) throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Delete the given entity and return the entity if the delete was applied.
|
||||
@@ -277,10 +275,10 @@ public interface AsyncCassandraOperations {
|
||||
*
|
||||
* @param entity must not be {@literal null}.
|
||||
* @param options may be {@literal null}.
|
||||
* @return the deleted entity.
|
||||
* @return the {@link WriteResult} for this operation.
|
||||
* @throws DataAccessException if there is any problem executing the query.
|
||||
*/
|
||||
<T> ListenableFuture<T> delete(T entity, QueryOptions options) throws DataAccessException;
|
||||
ListenableFuture<WriteResult> delete(Object entity, QueryOptions options) throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Remove the given object from the table by id.
|
||||
|
||||
@@ -195,7 +195,6 @@ public class AsyncCassandraTemplate implements AsyncCassandraOperations {
|
||||
return this.statementFactory;
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
private CqlIdentifier getTableName(Object entity) {
|
||||
return getMappingContext().getRequiredPersistentEntity(ClassUtils.getUserClass(entity)).getTableName();
|
||||
}
|
||||
@@ -418,7 +417,7 @@ public class AsyncCassandraTemplate implements AsyncCassandraOperations {
|
||||
*/
|
||||
@Override
|
||||
public <T> ListenableFuture<T> insert(T entity) {
|
||||
return insert(entity, null);
|
||||
return new MappingListenableFutureAdapter<>(insert(entity, null), writeResult -> entity);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -426,14 +425,14 @@ public class AsyncCassandraTemplate implements AsyncCassandraOperations {
|
||||
* @see org.springframework.data.cassandra.core.AsyncCassandraOperations#insert(java.lang.Object, org.springframework.data.cassandra.core.InsertOptions)
|
||||
*/
|
||||
@Override
|
||||
public <T> ListenableFuture<T> insert(T entity, InsertOptions options) {
|
||||
public ListenableFuture<WriteResult> insert(Object entity, InsertOptions options) {
|
||||
|
||||
Assert.notNull(entity, "Entity must not be null");
|
||||
|
||||
Insert insert = QueryUtils.createInsertQuery(getTableName(entity).toCql(), entity, options, getConverter());
|
||||
|
||||
return new MappingListenableFutureAdapter<>(getAsyncCqlOperations().execute(new AsyncStatementCallback(insert)),
|
||||
resultSet -> resultSet.wasApplied() ? entity : null);
|
||||
WriteResult::of);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -442,7 +441,7 @@ public class AsyncCassandraTemplate implements AsyncCassandraOperations {
|
||||
*/
|
||||
@Override
|
||||
public <T> ListenableFuture<T> update(T entity) {
|
||||
return update(entity, null);
|
||||
return new MappingListenableFutureAdapter<>(update(entity, null), writeResult -> entity);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -450,14 +449,14 @@ public class AsyncCassandraTemplate implements AsyncCassandraOperations {
|
||||
* @see org.springframework.data.cassandra.core.AsyncCassandraOperations#update(java.lang.Object, org.springframework.data.cassandra.core.UpdateOptions)
|
||||
*/
|
||||
@Override
|
||||
public <T> ListenableFuture<T> update(T entity, UpdateOptions options) {
|
||||
public ListenableFuture<WriteResult> update(Object entity, UpdateOptions options) {
|
||||
|
||||
Assert.notNull(entity, "Entity must not be null");
|
||||
|
||||
Update update = QueryUtils.createUpdateQuery(getTableName(entity).toCql(), entity, options, getConverter());
|
||||
|
||||
return new MappingListenableFutureAdapter<>(getAsyncCqlOperations().execute(new AsyncStatementCallback(update)),
|
||||
resultSet -> resultSet.wasApplied() ? entity : null);
|
||||
WriteResult::of);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -466,7 +465,7 @@ public class AsyncCassandraTemplate implements AsyncCassandraOperations {
|
||||
*/
|
||||
@Override
|
||||
public <T> ListenableFuture<T> delete(T entity) {
|
||||
return delete(entity, null);
|
||||
return new MappingListenableFutureAdapter<>(delete(entity, null), writeResult -> entity);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -474,14 +473,14 @@ public class AsyncCassandraTemplate implements AsyncCassandraOperations {
|
||||
* @see org.springframework.data.cassandra.core.AsyncCassandraOperations#delete(java.lang.Object, org.springframework.data.cql.core.QueryOptions)
|
||||
*/
|
||||
@Override
|
||||
public <T> ListenableFuture<T> delete(T entity, QueryOptions options) {
|
||||
public ListenableFuture<WriteResult> delete(Object entity, QueryOptions options) {
|
||||
|
||||
Assert.notNull(entity, "Entity must not be null");
|
||||
|
||||
Delete delete = QueryUtils.createDeleteQuery(getTableName(entity).toCql(), entity, options, getConverter());
|
||||
|
||||
return new MappingListenableFutureAdapter<>(getAsyncCqlOperations().execute(new AsyncStatementCallback(delete)),
|
||||
resultSet -> resultSet.wasApplied() ? entity : null);
|
||||
WriteResult::of);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -518,12 +517,12 @@ public class AsyncCassandraTemplate implements AsyncCassandraOperations {
|
||||
return new MappingListenableFutureAdapter<>(getAsyncCqlOperations().execute(truncate), aBoolean -> null);
|
||||
}
|
||||
|
||||
private static class MappingListenableFutureAdapter<T, S>
|
||||
static class MappingListenableFutureAdapter<T, S>
|
||||
extends org.springframework.util.concurrent.ListenableFutureAdapter<T, S> {
|
||||
|
||||
private final Function<S, T> mapper;
|
||||
|
||||
public MappingListenableFutureAdapter(ListenableFuture<S> adaptee, Function<S, T> mapper) {
|
||||
MappingListenableFutureAdapter(ListenableFuture<S> adaptee, Function<S, T> mapper) {
|
||||
super(adaptee);
|
||||
this.mapper = mapper;
|
||||
}
|
||||
|
||||
@@ -40,9 +40,10 @@ public interface CassandraBatchOperations {
|
||||
/**
|
||||
* Execute the batch. The batch can be executed only once.
|
||||
*
|
||||
* @return the {@link WriteResult} for the bulk operation.
|
||||
* @throws IllegalStateException if the batch is executed after it was executed already.
|
||||
*/
|
||||
void execute();
|
||||
WriteResult execute();
|
||||
|
||||
/**
|
||||
* Apply a given {@code timestamp} to the whole batch.
|
||||
|
||||
@@ -59,14 +59,15 @@ class CassandraBatchTemplate implements CassandraBatchOperations {
|
||||
* @see org.springframework.data.cassandra.core.CassandraBatchOperations#execute()
|
||||
*/
|
||||
@Override
|
||||
public void execute() {
|
||||
public WriteResult execute() {
|
||||
|
||||
if (executed.compareAndSet(false, true)) {
|
||||
operations.getCqlOperations().execute(batch);
|
||||
return;
|
||||
return WriteResult.of(operations.getCqlOperations().queryForResultSet(batch));
|
||||
}
|
||||
|
||||
assertNotExecuted();
|
||||
|
||||
return null; // code won't reach this line
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
|
||||
@@ -258,58 +258,55 @@ public interface CassandraOperations {
|
||||
* Insert the given entity and return the entity if the insert was applied.
|
||||
*
|
||||
* @param entity The entity to insert, must not be {@literal null}.
|
||||
* @return the inserted entity.
|
||||
* @throws DataAccessException if there is any problem executing the query.
|
||||
*/
|
||||
<T> T insert(T entity) throws DataAccessException;
|
||||
void insert(Object entity) throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Insert the given entity applying {@link WriteOptions} and return the entity if the insert was applied.
|
||||
*
|
||||
* @param entity The entity to insert, must not be {@literal null}.
|
||||
* @param options may be {@literal null}.
|
||||
* @return the inserted entity or {@literal null} if the {@code INSERT} operation was not applied.
|
||||
* @return the {@link WriteResult} for this operation.
|
||||
* @throws DataAccessException if there is any problem executing the query.
|
||||
*/
|
||||
<T> T insert(T entity, InsertOptions options) throws DataAccessException;
|
||||
WriteResult insert(Object entity, InsertOptions options) throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Update the given entity and return the entity if the update was applied.
|
||||
*
|
||||
* @param entity The entity to update, must not be {@literal null}.
|
||||
* @return the updated entity.
|
||||
* @throws DataAccessException if there is any problem executing the query.
|
||||
*/
|
||||
<T> T update(T entity) throws DataAccessException;
|
||||
void update(Object entity) throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Update the given entity applying {@link WriteOptions} and return the entity if the update was applied.
|
||||
*
|
||||
* @param entity The entity to update, must not be {@literal null}.
|
||||
* @param options may be {@literal null}.
|
||||
* @return the updated entity or {@literal null} if the {@code UPDATE} operation was not applied.
|
||||
* @return the {@link WriteResult} for this operation.
|
||||
* @throws DataAccessException if there is any problem executing the query.
|
||||
*/
|
||||
<T> T update(T entity, UpdateOptions options) throws DataAccessException;
|
||||
WriteResult update(Object entity, UpdateOptions options) throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Delete the given entity and return the entity if the delete was applied.
|
||||
*
|
||||
* @param entity must not be {@literal null}.
|
||||
* @return the deleted entity.
|
||||
* @throws DataAccessException if there is any problem executing the query.
|
||||
*/
|
||||
<T> T delete(T entity) throws DataAccessException;
|
||||
void delete(Object entity) throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Delete the given entity applying {@link QueryOptions} and return the entity if the delete was applied.
|
||||
*
|
||||
* @param entity must not be {@literal null}.
|
||||
* @param options may be {@literal null}.
|
||||
* @return the deleted entity.
|
||||
* @return the {@link WriteResult} for this operation.
|
||||
* @throws DataAccessException if there is any problem executing the query.
|
||||
*/
|
||||
<T> T delete(T entity, QueryOptions options) throws DataAccessException;
|
||||
WriteResult delete(Object entity, QueryOptions options) throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Remove the given object from the table by id.
|
||||
|
||||
@@ -15,6 +15,9 @@
|
||||
*/
|
||||
package org.springframework.data.cassandra.core;
|
||||
|
||||
import lombok.NonNull;
|
||||
import lombok.Value;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
@@ -425,8 +428,8 @@ public class CassandraTemplate implements CassandraOperations {
|
||||
* @see org.springframework.data.cassandra.core.CassandraOperations#insert(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public <T> T insert(T entity) {
|
||||
return insert(entity, null);
|
||||
public void insert(Object entity) {
|
||||
insert(entity, null);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -434,13 +437,13 @@ public class CassandraTemplate implements CassandraOperations {
|
||||
* @see org.springframework.data.cassandra.core.CassandraOperations#insert(java.lang.Object, org.springframework.data.cassandra.core.InsertOptions)
|
||||
*/
|
||||
@Override
|
||||
public <T> T insert(T entity, InsertOptions options) {
|
||||
public WriteResult insert(Object entity, InsertOptions options) {
|
||||
|
||||
Assert.notNull(entity, "Entity must not be null");
|
||||
|
||||
Insert insert = QueryUtils.createInsertQuery(getTableName(entity.getClass()).toCql(), entity, options, converter);
|
||||
|
||||
return getCqlOperations().execute(new StatementCallback<>(insert, entity));
|
||||
return getCqlOperations().execute(new StatementCallback(insert));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -448,8 +451,8 @@ public class CassandraTemplate implements CassandraOperations {
|
||||
* @see org.springframework.data.cassandra.core.CassandraOperations#update(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public <T> T update(T entity) {
|
||||
return update(entity, null);
|
||||
public void update(Object entity) {
|
||||
update(entity, null);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -457,13 +460,13 @@ public class CassandraTemplate implements CassandraOperations {
|
||||
* @see org.springframework.data.cassandra.core.CassandraOperations#update(java.lang.Object, org.springframework.data.cassandra.core.UpdateOptions)
|
||||
*/
|
||||
@Override
|
||||
public <T> T update(T entity, UpdateOptions options) {
|
||||
public WriteResult update(Object entity, UpdateOptions options) {
|
||||
|
||||
Assert.notNull(entity, "Entity must not be null");
|
||||
|
||||
Update update = QueryUtils.createUpdateQuery(getTableName(entity.getClass()).toCql(), entity, options, converter);
|
||||
|
||||
return getCqlOperations().execute(new StatementCallback<>(update, entity));
|
||||
return getCqlOperations().execute(new StatementCallback(update));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -471,8 +474,8 @@ public class CassandraTemplate implements CassandraOperations {
|
||||
* @see org.springframework.data.cassandra.core.CassandraOperations#delete(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public <T> T delete(T entity) {
|
||||
return delete(entity, null);
|
||||
public void delete(Object entity) {
|
||||
delete(entity, null);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -480,13 +483,13 @@ public class CassandraTemplate implements CassandraOperations {
|
||||
* @see org.springframework.data.cassandra.core.CassandraOperations#delete(java.lang.Object, org.springframework.data.cql.core.QueryOptions)
|
||||
*/
|
||||
@Override
|
||||
public <T> T delete(T entity, QueryOptions options) {
|
||||
public WriteResult delete(Object entity, QueryOptions options) {
|
||||
|
||||
Assert.notNull(entity, "Entity must not be null");
|
||||
|
||||
Delete delete = QueryUtils.createDeleteQuery(getTableName(entity.getClass()).toCql(), entity, options, converter);
|
||||
|
||||
return getCqlOperations().execute(new StatementCallback<>(delete, entity));
|
||||
return getCqlOperations().execute(new StatementCallback(delete));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -559,19 +562,14 @@ public class CassandraTemplate implements CassandraOperations {
|
||||
return StreamSupport.stream(iterable.spliterator(), false).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private static class StatementCallback<T> implements SessionCallback<T>, CqlProvider {
|
||||
@Value
|
||||
static class StatementCallback implements SessionCallback<WriteResult>, CqlProvider {
|
||||
|
||||
private final Statement statement;
|
||||
private final T entity;
|
||||
|
||||
StatementCallback(Statement statement, T entity) {
|
||||
this.statement = statement;
|
||||
this.entity = entity;
|
||||
}
|
||||
@NonNull Statement statement;
|
||||
|
||||
@Override
|
||||
public T doInSession(Session session) throws DriverException, DataAccessException {
|
||||
return session.execute(statement).wasApplied() ? entity : null;
|
||||
public WriteResult doInSession(Session session) throws DriverException, DataAccessException {
|
||||
return WriteResult.of(session.execute(statement));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -183,11 +183,10 @@ public interface ReactiveCassandraOperations {
|
||||
*
|
||||
* @param entity The entity to insert, must not be {@literal null}.
|
||||
* @param options may be {@literal null}.
|
||||
* @return the inserted entity or {@link Mono#empty()} if the {@code INSERT} operation was not applied.
|
||||
* @return the {@link WriteResult} for this operation.
|
||||
* @throws DataAccessException if there is any problem issuing the execution.
|
||||
*/
|
||||
<T> Mono<T> insert(T entity, InsertOptions options) throws DataAccessException;
|
||||
|
||||
Mono<WriteResult> insert(Object entity, InsertOptions options) throws DataAccessException;
|
||||
/**
|
||||
* Update the given entity and emit the entity if the update was applied.
|
||||
*
|
||||
@@ -202,11 +201,10 @@ public interface ReactiveCassandraOperations {
|
||||
*
|
||||
* @param entity The entity to update, must not be {@literal null}.
|
||||
* @param options may be {@literal null}.
|
||||
* @return the updated entity or {@link Mono#empty()} if the {@code UPDATE} operation was not applied.
|
||||
* @return the {@link WriteResult} for this operation.
|
||||
* @throws DataAccessException if there is any problem issuing the execution.
|
||||
*/
|
||||
<T> Mono<T> update(T entity, UpdateOptions options) throws DataAccessException;
|
||||
|
||||
Mono<WriteResult> update(Object entity, UpdateOptions options) throws DataAccessException;
|
||||
/**
|
||||
* Remove the given object from the table by id.
|
||||
*
|
||||
@@ -231,11 +229,10 @@ public interface ReactiveCassandraOperations {
|
||||
*
|
||||
* @param entity must not be {@literal null}.
|
||||
* @param options may be {@literal null}.
|
||||
* @return the deleted entity.
|
||||
* @return the {@link WriteResult} for this operation.
|
||||
* @throws DataAccessException if there is any problem issuing the execution.
|
||||
*/
|
||||
<T> Mono<T> delete(T entity, QueryOptions options) throws DataAccessException;
|
||||
|
||||
Mono<WriteResult> delete(Object entity, QueryOptions options) throws DataAccessException;
|
||||
/**
|
||||
* Execute a {@code TRUNCATE} query to remove all entities of a given class.
|
||||
*
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
package org.springframework.data.cassandra.core;
|
||||
|
||||
import lombok.NonNull;
|
||||
import lombok.Value;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
@@ -374,7 +376,7 @@ public class ReactiveCassandraTemplate implements ReactiveCassandraOperations {
|
||||
*/
|
||||
@Override
|
||||
public <T> Mono<T> insert(T entity) {
|
||||
return insert(entity, null);
|
||||
return insert(entity, null).map(writeResult -> entity);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -382,27 +384,13 @@ public class ReactiveCassandraTemplate implements ReactiveCassandraOperations {
|
||||
* @see org.springframework.data.cassandra.core.ReactiveCassandraOperations#insert(java.lang.Object, org.springframework.data.cassandra.core.InsertOptions)
|
||||
*/
|
||||
@Override
|
||||
public <T> Mono<T> insert(T entity, InsertOptions options) {
|
||||
public Mono<WriteResult> insert(Object entity, InsertOptions options) {
|
||||
|
||||
Assert.notNull(entity, "Entity must not be null");
|
||||
|
||||
Insert insert = QueryUtils.createInsertQuery(getTableName(entity).toCql(), entity, options, getConverter());
|
||||
|
||||
class InsertCallback implements ReactiveSessionCallback<T>, CqlProvider {
|
||||
|
||||
@Override
|
||||
public Publisher<T> doInSession(ReactiveSession session) throws DriverException, DataAccessException {
|
||||
return session.execute(insert)
|
||||
.flatMap(reactiveResultSet -> reactiveResultSet.wasApplied() ? Mono.just(entity) : Mono.empty());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCql() {
|
||||
return insert.toString();
|
||||
}
|
||||
}
|
||||
|
||||
return getReactiveCqlOperations().execute(new InsertCallback()).next();
|
||||
return getReactiveCqlOperations().execute(new StatementCallback(insert)).next();
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -411,7 +399,7 @@ public class ReactiveCassandraTemplate implements ReactiveCassandraOperations {
|
||||
*/
|
||||
@Override
|
||||
public <T> Mono<T> update(T entity) {
|
||||
return update(entity, null);
|
||||
return update(entity, null).map(writeResult -> entity);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -419,27 +407,13 @@ public class ReactiveCassandraTemplate implements ReactiveCassandraOperations {
|
||||
* @see org.springframework.data.cassandra.core.ReactiveCassandraOperations#update(java.lang.Object, org.springframework.data.cassandra.core.UpdateOptions)
|
||||
*/
|
||||
@Override
|
||||
public <T> Mono<T> update(T entity, UpdateOptions options) {
|
||||
public Mono<WriteResult> update(Object entity, UpdateOptions options) {
|
||||
|
||||
Assert.notNull(entity, "Entity must not be null");
|
||||
|
||||
Update update = QueryUtils.createUpdateQuery(getTableName(entity).toCql(), entity, options, converter);
|
||||
|
||||
class UpdateCallback implements ReactiveSessionCallback<T>, CqlProvider {
|
||||
|
||||
@Override
|
||||
public Publisher<T> doInSession(ReactiveSession session) throws DriverException, DataAccessException {
|
||||
return session.execute(update)
|
||||
.flatMap(reactiveResultSet -> reactiveResultSet.wasApplied() ? Mono.just(entity) : Mono.empty());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCql() {
|
||||
return update.toString();
|
||||
}
|
||||
}
|
||||
|
||||
return getReactiveCqlOperations().execute(new UpdateCallback()).next();
|
||||
return getReactiveCqlOperations().execute(new StatementCallback(update)).next();
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -467,7 +441,7 @@ public class ReactiveCassandraTemplate implements ReactiveCassandraOperations {
|
||||
*/
|
||||
@Override
|
||||
public <T> Mono<T> delete(T entity) {
|
||||
return delete(entity, null);
|
||||
return delete(entity, null).map(reactiveWriteResult -> entity);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -475,27 +449,13 @@ public class ReactiveCassandraTemplate implements ReactiveCassandraOperations {
|
||||
* @see org.springframework.data.cassandra.core.ReactiveCassandraOperations#delete(java.lang.Object, org.springframework.data.cql.core.QueryOptions)
|
||||
*/
|
||||
@Override
|
||||
public <T> Mono<T> delete(T entity, QueryOptions options) {
|
||||
public Mono<WriteResult> delete(Object entity, QueryOptions options) {
|
||||
|
||||
Assert.notNull(entity, "Entity must not be null");
|
||||
|
||||
Delete delete = QueryUtils.createDeleteQuery(getTableName(entity).toCql(), entity, options, getConverter());
|
||||
|
||||
class DeleteCallback implements ReactiveSessionCallback<T>, CqlProvider {
|
||||
|
||||
@Override
|
||||
public Publisher<T> doInSession(ReactiveSession session) throws DriverException, DataAccessException {
|
||||
return session.execute(delete)
|
||||
.flatMap(reactiveResultSet -> reactiveResultSet.wasApplied() ? Mono.just(entity) : Mono.empty());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCql() {
|
||||
return delete.toString();
|
||||
}
|
||||
}
|
||||
|
||||
return getReactiveCqlOperations().execute(new DeleteCallback()).next();
|
||||
return getReactiveCqlOperations().execute(new StatementCallback(delete)).next();
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -512,4 +472,26 @@ public class ReactiveCassandraTemplate implements ReactiveCassandraOperations {
|
||||
|
||||
return getReactiveCqlOperations().execute(truncate).then();
|
||||
}
|
||||
|
||||
@Value
|
||||
static class StatementCallback implements ReactiveSessionCallback<WriteResult>, CqlProvider {
|
||||
|
||||
@NonNull Statement statement;
|
||||
|
||||
@Override
|
||||
public Publisher<WriteResult> doInSession(ReactiveSession session) throws DriverException, DataAccessException {
|
||||
return session.execute(statement).flatMap(StatementCallback::toWriteResult);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCql() {
|
||||
return statement.toString();
|
||||
}
|
||||
|
||||
private static Mono<WriteResult> toWriteResult(ReactiveResultSet resultSet) {
|
||||
return resultSet.rows().collectList()
|
||||
.map(rows -> new WriteResult(resultSet.getAllExecutionInfo(), resultSet.wasApplied(), rows));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Copyright 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.core;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import com.datastax.driver.core.ExecutionInfo;
|
||||
import com.datastax.driver.core.ResultSet;
|
||||
import com.datastax.driver.core.Row;
|
||||
|
||||
/**
|
||||
* The result of a write operation.
|
||||
*
|
||||
* @author Mark Paluch
|
||||
* @since 2.0
|
||||
* @see ResultSet
|
||||
*/
|
||||
public class WriteResult {
|
||||
|
||||
private final List<ExecutionInfo> executionInfo;
|
||||
private final boolean wasApplied;
|
||||
private final List<Row> rows;
|
||||
|
||||
WriteResult(List<ExecutionInfo> executionInfo, boolean wasApplied, List<Row> rows) {
|
||||
|
||||
this.executionInfo = executionInfo;
|
||||
this.wasApplied = wasApplied;
|
||||
this.rows = rows;
|
||||
}
|
||||
|
||||
private WriteResult(ResultSet resultSet) {
|
||||
|
||||
this.executionInfo = resultSet.getAllExecutionInfo();
|
||||
this.wasApplied = resultSet.wasApplied();
|
||||
|
||||
int limit = resultSet.getAvailableWithoutFetching();
|
||||
|
||||
List<Row> rows = new ArrayList<>(limit);
|
||||
|
||||
for (int i = 0; i < limit; i++) {
|
||||
rows.add(resultSet.one());
|
||||
}
|
||||
|
||||
this.rows = Collections.unmodifiableList(rows);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a {@link WriteResult} from {@link ResultSet}.
|
||||
*
|
||||
* @param resultSet must not be {@literal null}.
|
||||
* @return the {@link WriteResult} for {@link ResultSet}.
|
||||
*/
|
||||
public static WriteResult of(ResultSet resultSet) {
|
||||
|
||||
Assert.notNull(resultSet, "ResultSet must not be null");
|
||||
|
||||
return new WriteResult(resultSet);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {@literal true} if the write was applied.
|
||||
*/
|
||||
public boolean wasApplied() {
|
||||
return wasApplied;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the list of {@link ExecutionInfo}.
|
||||
*/
|
||||
public List<ExecutionInfo> getExecutionInfo() {
|
||||
return executionInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the {@link Row rows} returned by the write operation.
|
||||
*/
|
||||
public List<Row> getRows() {
|
||||
return rows;
|
||||
}
|
||||
}
|
||||
@@ -123,7 +123,9 @@ public class SimpleCassandraRepository<T, ID> implements CassandraRepository<T,
|
||||
|
||||
Assert.notNull(entity, "Entity must not be null");
|
||||
|
||||
return operations.insert(entity);
|
||||
operations.insert(entity);
|
||||
|
||||
return entity;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
@@ -137,12 +139,8 @@ public class SimpleCassandraRepository<T, ID> implements CassandraRepository<T,
|
||||
List<S> result = new ArrayList<>();
|
||||
|
||||
for (S entity : entities) {
|
||||
|
||||
S saved = operations.insert(entity);
|
||||
|
||||
if (saved != null) {
|
||||
result.add(saved);
|
||||
}
|
||||
result.add(entity);
|
||||
operations.insert(entity);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
@@ -114,9 +114,9 @@ public class AsyncCassandraTemplateIntegrationTests extends AbstractKeyspaceCrea
|
||||
|
||||
User user = new User("heisenberg", "Walter", "White");
|
||||
|
||||
ListenableFuture<User> inserted = template.insert(user, lwtOptions);
|
||||
ListenableFuture<WriteResult> inserted = template.insert(user, lwtOptions);
|
||||
|
||||
assertThat(getUninterruptibly(inserted)).isEqualTo(user);
|
||||
assertThat(getUninterruptibly(inserted).wasApplied()).isTrue();
|
||||
}
|
||||
|
||||
@Test // DATACASS-250
|
||||
@@ -130,9 +130,9 @@ public class AsyncCassandraTemplateIntegrationTests extends AbstractKeyspaceCrea
|
||||
|
||||
user.setFirstname("Walter Hartwell");
|
||||
|
||||
ListenableFuture<User> lwt = template.insert(user, lwtOptions);
|
||||
ListenableFuture<WriteResult> lwt = template.insert(user, lwtOptions);
|
||||
|
||||
assertThat(getUninterruptibly(lwt)).isNull();
|
||||
assertThat(getUninterruptibly(lwt).wasApplied()).isFalse();
|
||||
assertThat(getUser(user.getId()).getFirstname()).isEqualTo("Walter");
|
||||
}
|
||||
|
||||
@@ -168,9 +168,9 @@ public class AsyncCassandraTemplateIntegrationTests extends AbstractKeyspaceCrea
|
||||
|
||||
User user = new User("heisenberg", "Walter", "White");
|
||||
|
||||
ListenableFuture<User> lwt = template.update(user, lwtOptions);
|
||||
ListenableFuture<WriteResult> lwt = template.update(user, lwtOptions);
|
||||
|
||||
assertThat(getUninterruptibly(lwt)).isNull();
|
||||
assertThat(getUninterruptibly(lwt).wasApplied()).isFalse();
|
||||
assertThat(getUser(user.getId())).isNull();
|
||||
}
|
||||
|
||||
@@ -184,9 +184,9 @@ public class AsyncCassandraTemplateIntegrationTests extends AbstractKeyspaceCrea
|
||||
|
||||
user.setFirstname("Walter Hartwell");
|
||||
|
||||
ListenableFuture<User> updated = template.update(user, lwtOptions);
|
||||
ListenableFuture<WriteResult> updated = template.update(user, lwtOptions);
|
||||
|
||||
assertThat(getUninterruptibly(updated)).isNotNull();
|
||||
assertThat(getUninterruptibly(updated).wasApplied()).isTrue();
|
||||
assertThat(getUser(user.getId()).getFirstname()).isEqualTo("Walter Hartwell");
|
||||
}
|
||||
|
||||
|
||||
@@ -256,18 +256,6 @@ public class AsyncCassandraTemplateUnitTests {
|
||||
}
|
||||
}
|
||||
|
||||
@Test // DATACASS-292
|
||||
public void insertShouldNotApplyInsert() {
|
||||
|
||||
when(resultSet.wasApplied()).thenReturn(false);
|
||||
|
||||
User user = new User("heisenberg", "Walter", "White");
|
||||
|
||||
ListenableFuture<User> future = template.insert(user);
|
||||
|
||||
assertThat(getUninterruptibly(future)).isNull();
|
||||
}
|
||||
|
||||
@Test // DATACASS-292
|
||||
public void updateShouldUpdateEntity() {
|
||||
|
||||
@@ -302,18 +290,6 @@ public class AsyncCassandraTemplateUnitTests {
|
||||
}
|
||||
}
|
||||
|
||||
@Test // DATACASS-292
|
||||
public void updateShouldNotApplyUpdate() {
|
||||
|
||||
when(resultSet.wasApplied()).thenReturn(false);
|
||||
|
||||
User user = new User("heisenberg", "Walter", "White");
|
||||
|
||||
ListenableFuture<User> future = template.update(user);
|
||||
|
||||
assertThat(getUninterruptibly(future)).isNull();
|
||||
}
|
||||
|
||||
@Test // DATACASS-292
|
||||
public void deleteByIdShouldRemoveEntity() {
|
||||
|
||||
@@ -361,18 +337,6 @@ public class AsyncCassandraTemplateUnitTests {
|
||||
}
|
||||
}
|
||||
|
||||
@Test // DATACASS-292
|
||||
public void deleteShouldNotApplyRemoval() {
|
||||
|
||||
when(resultSet.wasApplied()).thenReturn(false);
|
||||
|
||||
User user = new User("heisenberg", "Walter", "White");
|
||||
|
||||
ListenableFuture<User> future = template.delete(user);
|
||||
|
||||
assertThat(getUninterruptibly(future)).isNull();
|
||||
}
|
||||
|
||||
@Test // DATACASS-292
|
||||
public void truncateShouldRemoveEntities() {
|
||||
|
||||
|
||||
@@ -85,7 +85,7 @@ public class CassandraBatchTemplateIntegrationTests extends AbstractKeyspaceCrea
|
||||
walter.setAge(100);
|
||||
|
||||
CassandraBatchOperations batchOperations = new CassandraBatchTemplate(template);
|
||||
batchOperations.insert(Collections.singleton(walter), lwtOptions).insert(mike).execute();
|
||||
WriteResult writeResult = batchOperations.insert(Collections.singleton(walter), lwtOptions).insert(mike).execute();
|
||||
|
||||
Group loadedWalter = template.selectOneById(walter.getId(), Group.class);
|
||||
Group loadedMike = template.selectOneById(mike.getId(), Group.class);
|
||||
@@ -94,6 +94,9 @@ public class CassandraBatchTemplateIntegrationTests extends AbstractKeyspaceCrea
|
||||
assertThat(loadedWalter.getAge()).isEqualTo(42);
|
||||
|
||||
assertThat(loadedMike).isNotNull();
|
||||
assertThat(writeResult.wasApplied()).isFalse();
|
||||
assertThat(writeResult.getExecutionInfo()).isNotEmpty();
|
||||
assertThat(writeResult.getRows()).isNotEmpty();
|
||||
}
|
||||
|
||||
@Test // DATACASS-288
|
||||
@@ -180,8 +183,11 @@ public class CassandraBatchTemplateIntegrationTests extends AbstractKeyspaceCrea
|
||||
@Test // DATACASS-288
|
||||
public void shouldUpdatesCollectionOfEntities() {
|
||||
|
||||
FlatGroup walter = template.insert(new FlatGroup("users", "0x1", "walter"));
|
||||
FlatGroup mike = template.insert(new FlatGroup("users", "0x1", "mike"));
|
||||
FlatGroup walter = new FlatGroup("users", "0x1", "walter");
|
||||
FlatGroup mike = new FlatGroup("users", "0x1", "mike");
|
||||
|
||||
template.insert(walter);
|
||||
template.insert(mike);
|
||||
|
||||
walter.setEmail("walter@white.com");
|
||||
mike.setEmail("mike@sauls.com");
|
||||
|
||||
@@ -140,9 +140,8 @@ public class CassandraTemplateIntegrationTests extends AbstractKeyspaceCreatingI
|
||||
|
||||
assertThat(template.selectOneById(user.getId(), User.class)).isNull();
|
||||
|
||||
User inserted = template.insert(user);
|
||||
template.insert(user);
|
||||
|
||||
assertThat(inserted).isEqualTo(user);
|
||||
assertThat(template.selectOneById(user.getId(), User.class)).isEqualTo(user);
|
||||
}
|
||||
|
||||
@@ -153,9 +152,9 @@ public class CassandraTemplateIntegrationTests extends AbstractKeyspaceCreatingI
|
||||
|
||||
User user = new User("heisenberg", "Walter", "White");
|
||||
|
||||
User inserted = template.insert(user, lwtOptions);
|
||||
template.insert(user, lwtOptions);
|
||||
|
||||
assertThat(inserted).isEqualTo(user);
|
||||
assertThat(template.selectOneById(user.getId(), User.class)).isNotNull();
|
||||
}
|
||||
|
||||
@Test // DATACASS-250
|
||||
@@ -169,9 +168,9 @@ public class CassandraTemplateIntegrationTests extends AbstractKeyspaceCreatingI
|
||||
|
||||
user.setFirstname("Walter Hartwell");
|
||||
|
||||
User lwt = template.insert(user, lwtOptions);
|
||||
WriteResult lwt = template.insert(user, lwtOptions);
|
||||
|
||||
assertThat(lwt).isNull();
|
||||
assertThat(lwt.wasApplied()).isFalse();
|
||||
assertThat(template.selectOneById(user.getId(), User.class).getFirstname()).isEqualTo("Walter");
|
||||
}
|
||||
|
||||
@@ -194,9 +193,8 @@ public class CassandraTemplateIntegrationTests extends AbstractKeyspaceCreatingI
|
||||
|
||||
user.setFirstname("Walter Hartwell");
|
||||
|
||||
User updated = template.update(user);
|
||||
template.update(user);
|
||||
|
||||
assertThat(updated).isNotNull();
|
||||
assertThat(template.selectOneById(user.getId(), User.class)).isEqualTo(user);
|
||||
}
|
||||
|
||||
@@ -207,9 +205,9 @@ public class CassandraTemplateIntegrationTests extends AbstractKeyspaceCreatingI
|
||||
|
||||
User user = new User("heisenberg", "Walter", "White");
|
||||
|
||||
User lwt = template.update(user, lwtOptions);
|
||||
WriteResult lwt = template.update(user, lwtOptions);
|
||||
|
||||
assertThat(lwt).isNull();
|
||||
assertThat(lwt.wasApplied()).isFalse();
|
||||
assertThat(template.selectOneById(user.getId(), User.class)).isNull();
|
||||
}
|
||||
|
||||
@@ -223,9 +221,9 @@ public class CassandraTemplateIntegrationTests extends AbstractKeyspaceCreatingI
|
||||
|
||||
user.setFirstname("Walter Hartwell");
|
||||
|
||||
User updated = template.update(user, lwtOptions);
|
||||
WriteResult lwt = template.update(user, lwtOptions);
|
||||
|
||||
assertThat(updated).isNotNull();
|
||||
assertThat(lwt.wasApplied()).isTrue();
|
||||
assertThat(template.selectOneById(user.getId(), User.class).getFirstname()).isEqualTo("Walter Hartwell");
|
||||
}
|
||||
|
||||
@@ -275,9 +273,8 @@ public class CassandraTemplateIntegrationTests extends AbstractKeyspaceCreatingI
|
||||
User user = new User("heisenberg", "Walter", "White");
|
||||
template.insert(user);
|
||||
|
||||
User deleted = template.delete(user);
|
||||
template.delete(user);
|
||||
|
||||
assertThat(deleted).isNotNull();
|
||||
assertThat(template.selectOneById(user.getId(), User.class)).isNull();
|
||||
}
|
||||
|
||||
|
||||
@@ -196,9 +196,8 @@ public class CassandraTemplateUnitTests {
|
||||
|
||||
User user = new User("heisenberg", "Walter", "White");
|
||||
|
||||
User inserted = template.insert(user);
|
||||
template.insert(user);
|
||||
|
||||
assertThat(inserted).isEqualTo(user);
|
||||
verify(session).execute(statementCaptor.capture());
|
||||
assertThat(statementCaptor.getValue().toString())
|
||||
.isEqualTo("INSERT INTO users (firstname,id,lastname) VALUES ('Walter','heisenberg','White');");
|
||||
@@ -213,9 +212,8 @@ public class CassandraTemplateUnitTests {
|
||||
|
||||
User user = new User("heisenberg", "Walter", "White");
|
||||
|
||||
User inserted = template.insert(user, insertOptions);
|
||||
template.insert(user, insertOptions);
|
||||
|
||||
assertThat(inserted).isEqualTo(user);
|
||||
verify(session).execute(statementCaptor.capture());
|
||||
assertThat(statementCaptor.getValue().toString())
|
||||
.isEqualTo("INSERT INTO users (firstname,id,lastname) VALUES ('Walter','heisenberg','White') IF NOT EXISTS;");
|
||||
@@ -243,9 +241,9 @@ public class CassandraTemplateUnitTests {
|
||||
|
||||
User user = new User("heisenberg", "Walter", "White");
|
||||
|
||||
User inserted = template.insert(user);
|
||||
WriteResult writeResult = template.insert(user, InsertOptions.builder().build());
|
||||
|
||||
assertThat(inserted).isNull();
|
||||
assertThat(writeResult.wasApplied()).isFalse();
|
||||
}
|
||||
|
||||
@Test // DATACASS-292
|
||||
@@ -255,9 +253,8 @@ public class CassandraTemplateUnitTests {
|
||||
|
||||
User user = new User("heisenberg", "Walter", "White");
|
||||
|
||||
User updated = template.update(user);
|
||||
template.update(user);
|
||||
|
||||
assertThat(updated).isEqualTo(user);
|
||||
verify(session).execute(statementCaptor.capture());
|
||||
assertThat(statementCaptor.getValue().toString())
|
||||
.isEqualTo("UPDATE users SET firstname='Walter',lastname='White' WHERE id='heisenberg';");
|
||||
@@ -272,9 +269,9 @@ public class CassandraTemplateUnitTests {
|
||||
|
||||
User user = new User("heisenberg", "Walter", "White");
|
||||
|
||||
User updated = template.update(user, updateOptions);
|
||||
WriteResult writeResult = template.update(user, updateOptions);
|
||||
|
||||
assertThat(updated).isEqualTo(user);
|
||||
assertThat(writeResult.wasApplied()).isTrue();
|
||||
verify(session).execute(statementCaptor.capture());
|
||||
assertThat(statementCaptor.getValue().toString())
|
||||
.isEqualTo("UPDATE users SET firstname='Walter',lastname='White' WHERE id='heisenberg' IF EXISTS;");
|
||||
@@ -295,18 +292,6 @@ public class CassandraTemplateUnitTests {
|
||||
}
|
||||
}
|
||||
|
||||
@Test // DATACASS-292
|
||||
public void updateShouldNotApplyUpdate() {
|
||||
|
||||
when(resultSet.wasApplied()).thenReturn(false);
|
||||
|
||||
User user = new User("heisenberg", "Walter", "White");
|
||||
|
||||
User updated = template.update(user);
|
||||
|
||||
assertThat(updated).isNull();
|
||||
}
|
||||
|
||||
@Test // DATACASS-292
|
||||
public void deleteByIdShouldRemoveEntity() {
|
||||
|
||||
@@ -328,9 +313,8 @@ public class CassandraTemplateUnitTests {
|
||||
|
||||
User user = new User("heisenberg", "Walter", "White");
|
||||
|
||||
User deleted = template.delete(user);
|
||||
template.delete(user);
|
||||
|
||||
assertThat(deleted).isEqualTo(user);
|
||||
verify(session).execute(statementCaptor.capture());
|
||||
assertThat(statementCaptor.getValue().toString()).isEqualTo("DELETE FROM users WHERE id='heisenberg';");
|
||||
}
|
||||
@@ -350,18 +334,6 @@ public class CassandraTemplateUnitTests {
|
||||
}
|
||||
}
|
||||
|
||||
@Test // DATACASS-292
|
||||
public void deleteShouldNotApplyRemoval() {
|
||||
|
||||
when(resultSet.wasApplied()).thenReturn(false);
|
||||
|
||||
User user = new User("heisenberg", "Walter", "White");
|
||||
|
||||
User deleted = template.delete(user);
|
||||
|
||||
assertThat(deleted).isNull();
|
||||
}
|
||||
|
||||
@Test // DATACASS-292
|
||||
public void truncateShouldRemoveEntities() {
|
||||
|
||||
|
||||
@@ -83,9 +83,9 @@ public class ReactiveCassandraTemplateIntegrationTests extends AbstractKeyspaceC
|
||||
|
||||
User user = new User("heisenberg", "Walter", "White");
|
||||
|
||||
Mono<User> inserted = template.insert(user, lwtOptions);
|
||||
Mono<WriteResult> inserted = template.insert(user, lwtOptions);
|
||||
|
||||
StepVerifier.create(inserted).expectNext(user).verifyComplete();
|
||||
StepVerifier.create(inserted.map(WriteResult::wasApplied)).expectNext(true).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATACASS-250
|
||||
@@ -95,11 +95,13 @@ public class ReactiveCassandraTemplateIntegrationTests extends AbstractKeyspaceC
|
||||
|
||||
User user = new User("heisenberg", "Walter", "White");
|
||||
|
||||
StepVerifier.create(template.insert(user, lwtOptions)).expectNext(user).verifyComplete();
|
||||
StepVerifier.create(template.insert(user, lwtOptions).map(WriteResult::wasApplied)).expectNext(true)
|
||||
.verifyComplete();
|
||||
|
||||
user.setFirstname("Walter Hartwell");
|
||||
|
||||
StepVerifier.create(template.insert(user, lwtOptions)).verifyComplete();
|
||||
StepVerifier.create(template.insert(user, lwtOptions).map(WriteResult::wasApplied)).expectNext(false)
|
||||
.verifyComplete();
|
||||
|
||||
verifyUser(user.getId()).consumeNextWith(it -> assertThat(it.getFirstname()).isEqualTo("Walter")).verifyComplete();
|
||||
}
|
||||
@@ -135,7 +137,8 @@ public class ReactiveCassandraTemplateIntegrationTests extends AbstractKeyspaceC
|
||||
|
||||
User user = new User("heisenberg", "Walter", "White");
|
||||
|
||||
StepVerifier.create(template.update(user, lwtOptions)).verifyComplete();
|
||||
StepVerifier.create(template.update(user, lwtOptions).map(WriteResult::wasApplied)).expectNext(false)
|
||||
.verifyComplete();
|
||||
|
||||
verifyUser(user.getId()).verifyComplete();
|
||||
}
|
||||
|
||||
@@ -166,6 +166,7 @@ public class ReactiveCassandraTemplateUnitTests {
|
||||
public void insertShouldInsertEntity() {
|
||||
|
||||
when(reactiveResultSet.wasApplied()).thenReturn(true);
|
||||
when(reactiveResultSet.rows()).thenReturn(Flux.just(row));
|
||||
|
||||
User user = new User("heisenberg", "Walter", "White");
|
||||
StepVerifier.create(template.insert(user)).expectNext(user).verifyComplete();
|
||||
@@ -189,20 +190,11 @@ public class ReactiveCassandraTemplateUnitTests {
|
||||
}).verify();
|
||||
}
|
||||
|
||||
@Test // DATACASS-335
|
||||
public void insertShouldNotApplyInsert() {
|
||||
|
||||
when(reactiveResultSet.wasApplied()).thenReturn(false);
|
||||
|
||||
User user = new User("heisenberg", "Walter", "White");
|
||||
|
||||
StepVerifier.create(template.insert(user)).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATACASS-335
|
||||
public void updateShouldUpdateEntity() {
|
||||
|
||||
when(reactiveResultSet.wasApplied()).thenReturn(true);
|
||||
when(reactiveResultSet.rows()).thenReturn(Flux.just(row));
|
||||
|
||||
User user = new User("heisenberg", "Walter", "White");
|
||||
|
||||
@@ -213,20 +205,11 @@ public class ReactiveCassandraTemplateUnitTests {
|
||||
.isEqualTo("UPDATE users SET firstname='Walter',lastname='White' WHERE id='heisenberg';");
|
||||
}
|
||||
|
||||
@Test // DATACASS-335
|
||||
public void updateShouldNotApplyUpdate() {
|
||||
|
||||
when(reactiveResultSet.wasApplied()).thenReturn(false);
|
||||
|
||||
User user = new User("heisenberg", "Walter", "White");
|
||||
|
||||
StepVerifier.create(template.update(user)).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATACASS-335
|
||||
public void deleteShouldRemoveEntity() {
|
||||
|
||||
when(reactiveResultSet.wasApplied()).thenReturn(true);
|
||||
when(reactiveResultSet.rows()).thenReturn(Flux.just(row));
|
||||
|
||||
User user = new User("heisenberg", "Walter", "White");
|
||||
|
||||
@@ -236,16 +219,6 @@ public class ReactiveCassandraTemplateUnitTests {
|
||||
assertThat(statementCaptor.getValue().toString()).isEqualTo("DELETE FROM users WHERE id='heisenberg';");
|
||||
}
|
||||
|
||||
@Test // DATACASS-335
|
||||
public void deleteShouldNotApplyRemoval() {
|
||||
|
||||
when(reactiveResultSet.wasApplied()).thenReturn(false);
|
||||
|
||||
User user = new User("heisenberg", "Walter", "White");
|
||||
|
||||
StepVerifier.create(template.delete(user)).verifyComplete();
|
||||
}
|
||||
|
||||
@Test // DATACASS-335
|
||||
public void truncateShouldRemoveEntities() {
|
||||
|
||||
|
||||
@@ -58,23 +58,20 @@ public class CassandraTemplateMapIdProxyDelegateIntegrationTests extends Abstrac
|
||||
// insert
|
||||
SinglePkc inserted = new SinglePkc(uuid());
|
||||
inserted.setValue(uuid());
|
||||
SinglePkc saved = operations.insert(inserted);
|
||||
assertThat(inserted).isSameAs(saved);
|
||||
operations.insert(inserted);
|
||||
|
||||
// select
|
||||
SinglePkcId id = id(SinglePkcId.class).key(saved.getKey());
|
||||
SinglePkcId id = id(SinglePkcId.class).key(inserted.getKey());
|
||||
SinglePkc selected = operations.selectOneById(id, SinglePkc.class);
|
||||
assertThat(saved).isNotSameAs(selected);
|
||||
assertThat(selected.getKey()).isEqualTo(saved.getKey());
|
||||
assertThat(selected.getValue()).isEqualTo(saved.getValue());
|
||||
assertThat(inserted).isNotSameAs(selected);
|
||||
assertThat(selected.getKey()).isEqualTo(inserted.getKey());
|
||||
assertThat(selected.getValue()).isEqualTo(inserted.getValue());
|
||||
|
||||
// update
|
||||
selected.setValue(uuid());
|
||||
SinglePkc updated = operations.update(selected);
|
||||
assertThat(selected).isSameAs(updated);
|
||||
operations.update(selected);
|
||||
|
||||
selected = operations.selectOneById(id, SinglePkc.class);
|
||||
assertThat(updated).isNotSameAs(selected);
|
||||
SinglePkc updated = operations.selectOneById(id, SinglePkc.class);
|
||||
assertThat(selected.getValue()).isEqualTo(updated.getValue());
|
||||
|
||||
// delete
|
||||
@@ -122,23 +119,20 @@ public class CassandraTemplateMapIdProxyDelegateIntegrationTests extends Abstrac
|
||||
// insert
|
||||
MultiPkc inserted = new MultiPkc(uuid(), uuid());
|
||||
inserted.setValue(uuid());
|
||||
MultiPkc saved = operations.insert(inserted);
|
||||
assertThat(inserted).isSameAs(saved);
|
||||
operations.insert(inserted);
|
||||
|
||||
// select
|
||||
MultiPkcId id = id(MultiPkcId.class).key0(saved.getKey0()).key1(saved.getKey1());
|
||||
MultiPkcId id = id(MultiPkcId.class).key0(inserted.getKey0()).key1(inserted.getKey1());
|
||||
MultiPkc selected = operations.selectOneById(id, MultiPkc.class);
|
||||
assertThat(saved).isNotSameAs(selected);
|
||||
assertThat(selected.getKey0()).isEqualTo(saved.getKey0());
|
||||
assertThat(selected.getKey1()).isEqualTo(saved.getKey1());
|
||||
assertThat(selected.getValue()).isEqualTo(saved.getValue());
|
||||
assertThat(selected.getKey0()).isEqualTo(inserted.getKey0());
|
||||
assertThat(selected.getKey1()).isEqualTo(inserted.getKey1());
|
||||
assertThat(selected.getValue()).isEqualTo(inserted.getValue());
|
||||
|
||||
// update
|
||||
selected.setValue(uuid());
|
||||
MultiPkc updated = operations.update(selected);
|
||||
assertThat(selected).isSameAs(updated);
|
||||
operations.update(selected);
|
||||
|
||||
selected = operations.selectOneById(id, MultiPkc.class);
|
||||
MultiPkc updated = operations.selectOneById(id, MultiPkc.class);
|
||||
assertThat(updated).isNotSameAs(selected);
|
||||
assertThat(selected.getValue()).isEqualTo(updated.getValue());
|
||||
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.cassandra.test.integration.mapping.mapid.template;
|
||||
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
@@ -58,22 +57,19 @@ public class CassandraTemplateMapIdIntegrationTest extends AbstractKeyspaceCreat
|
||||
// insert
|
||||
SinglePkc inserted = new SinglePkc(uuid());
|
||||
inserted.setValue(uuid());
|
||||
SinglePkc saved = operations.insert(inserted);
|
||||
assertThat(inserted).isSameAs(saved);
|
||||
operations.insert(inserted);
|
||||
|
||||
// select
|
||||
MapId id = id("key", saved.getKey());
|
||||
MapId id = id("key", inserted.getKey());
|
||||
SinglePkc selected = operations.selectOneById(id, SinglePkc.class);
|
||||
assertThat(saved).isNotSameAs(selected);
|
||||
assertThat(selected.getKey()).isEqualTo(saved.getKey());
|
||||
assertThat(selected.getValue()).isEqualTo(saved.getValue());
|
||||
assertThat(selected.getKey()).isEqualTo(inserted.getKey());
|
||||
assertThat(selected.getValue()).isEqualTo(inserted.getValue());
|
||||
|
||||
// update
|
||||
selected.setValue(uuid());
|
||||
SinglePkc updated = operations.update(selected);
|
||||
assertThat(selected).isSameAs(updated);
|
||||
operations.update(selected);
|
||||
|
||||
selected = operations.selectOneById(id, SinglePkc.class);
|
||||
SinglePkc updated = operations.selectOneById(id, SinglePkc.class);
|
||||
assertThat(updated).isNotSameAs(selected);
|
||||
assertThat(selected.getValue()).isEqualTo(updated.getValue());
|
||||
|
||||
@@ -110,37 +106,6 @@ public class CassandraTemplateMapIdIntegrationTest extends AbstractKeyspaceCreat
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultiPkc() {
|
||||
|
||||
// insert
|
||||
MultiPkc inserted = new MultiPkc(uuid(), uuid());
|
||||
inserted.setValue(uuid());
|
||||
MultiPkc saved = operations.insert(inserted);
|
||||
assertThat(inserted).isSameAs(saved);
|
||||
|
||||
// select
|
||||
MapId id = id("key0", saved.getKey0()).with("key1", saved.getKey1());
|
||||
MultiPkc selected = operations.selectOneById(id, MultiPkc.class);
|
||||
assertThat(saved).isNotSameAs(selected);
|
||||
assertThat(selected.getKey0()).isEqualTo(saved.getKey0());
|
||||
assertThat(selected.getKey1()).isEqualTo(saved.getKey1());
|
||||
assertThat(selected.getValue()).isEqualTo(saved.getValue());
|
||||
|
||||
// update
|
||||
selected.setValue(uuid());
|
||||
MultiPkc updated = operations.update(selected);
|
||||
assertThat(selected).isSameAs(updated);
|
||||
|
||||
selected = operations.selectOneById(id, MultiPkc.class);
|
||||
assertThat(updated).isNotSameAs(selected);
|
||||
assertThat(selected.getValue()).isEqualTo(updated.getValue());
|
||||
|
||||
// delete
|
||||
operations.delete(selected);
|
||||
assertThat(operations.selectOneById(id, MultiPkc.class)).isNull();
|
||||
}
|
||||
|
||||
@Table
|
||||
public static class MultiPkc {
|
||||
|
||||
|
||||
@@ -1159,13 +1159,13 @@ Person qp = cassandraTemplate.selectOne(query(where("age").is(33)), Person.class
|
||||
|
||||
The insert/save operations available to you are listed below.
|
||||
|
||||
* `T` *insert* `(T objectToSave)` Insert the object in an Apache Cassandra table.
|
||||
* `T` *insert* `(T objectToSave, InsertOptions options)` Insert the object in an Apache Cassandra table applying `InsertOptions`.
|
||||
* `void` *insert* `(Object objectToSave)` Insert the object in an Apache Cassandra table.
|
||||
* `WriteResult` *insert* `(Object objectToSave, InsertOptions options)` Insert the object in an Apache Cassandra table applying `InsertOptions`.
|
||||
|
||||
A similar set of update operations is listed below
|
||||
|
||||
* `T` *update* `(T objectToSave)` Update the object in an Apache Cassandra table.
|
||||
* `T` *update* `(T objectToSave, UpdateOptions options)` Update the object in an Apache Cassandra table applying `UpdateOptions`.
|
||||
* `void` *update* `(Object objectToSave)` Update the object in an Apache Cassandra table.
|
||||
* `WriteResult` *update* `(Object objectToSave, UpdateOptions options)` Update the object in an Apache Cassandra table applying `UpdateOptions`.
|
||||
|
||||
Then, there is always the old fashioned way. You can write your own CQL statements. You can configure with `InsertOptions` and `UpdateOptions`
|
||||
additional options such as TTL, consistency level and lightweight transactions.
|
||||
|
||||
Reference in New Issue
Block a user