diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/AsyncCassandraTemplate.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/AsyncCassandraTemplate.java index 5623b0e8b..7ae6c3d21 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/AsyncCassandraTemplate.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/AsyncCassandraTemplate.java @@ -23,6 +23,24 @@ import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.StreamSupport; +import com.datastax.oss.driver.api.core.CqlIdentifier; +import com.datastax.oss.driver.api.core.CqlSession; +import com.datastax.oss.driver.api.core.DriverException; +import com.datastax.oss.driver.api.core.config.DefaultDriverOption; +import com.datastax.oss.driver.api.core.cql.AsyncResultSet; +import com.datastax.oss.driver.api.core.cql.BoundStatement; +import com.datastax.oss.driver.api.core.cql.PreparedStatement; +import com.datastax.oss.driver.api.core.cql.ResultSet; +import com.datastax.oss.driver.api.core.cql.Row; +import com.datastax.oss.driver.api.core.cql.SimpleStatement; +import com.datastax.oss.driver.api.core.cql.Statement; +import com.datastax.oss.driver.api.querybuilder.QueryBuilder; +import com.datastax.oss.driver.api.querybuilder.delete.Delete; +import com.datastax.oss.driver.api.querybuilder.insert.Insert; +import com.datastax.oss.driver.api.querybuilder.insert.RegularInsert; +import com.datastax.oss.driver.api.querybuilder.select.Select; +import com.datastax.oss.driver.api.querybuilder.truncate.Truncate; +import com.datastax.oss.driver.api.querybuilder.update.Update; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -66,25 +84,6 @@ import org.springframework.scheduling.annotation.AsyncResult; import org.springframework.util.Assert; import org.springframework.util.concurrent.ListenableFuture; -import com.datastax.oss.driver.api.core.CqlIdentifier; -import com.datastax.oss.driver.api.core.CqlSession; -import com.datastax.oss.driver.api.core.DriverException; -import com.datastax.oss.driver.api.core.config.DefaultDriverOption; -import com.datastax.oss.driver.api.core.cql.AsyncResultSet; -import com.datastax.oss.driver.api.core.cql.BoundStatement; -import com.datastax.oss.driver.api.core.cql.PreparedStatement; -import com.datastax.oss.driver.api.core.cql.ResultSet; -import com.datastax.oss.driver.api.core.cql.Row; -import com.datastax.oss.driver.api.core.cql.SimpleStatement; -import com.datastax.oss.driver.api.core.cql.Statement; -import com.datastax.oss.driver.api.querybuilder.QueryBuilder; -import com.datastax.oss.driver.api.querybuilder.delete.Delete; -import com.datastax.oss.driver.api.querybuilder.insert.Insert; -import com.datastax.oss.driver.api.querybuilder.insert.RegularInsert; -import com.datastax.oss.driver.api.querybuilder.select.Select; -import com.datastax.oss.driver.api.querybuilder.truncate.Truncate; -import com.datastax.oss.driver.api.querybuilder.update.Update; - /** * Primary implementation of {@link AsyncCassandraOperations}. It simplifies the use of asynchronous Cassandra usage and * helps to avoid common errors. It executes core Cassandra workflow. This class executes CQL queries or updates, @@ -434,7 +433,8 @@ public class AsyncCassandraTemplate Assert.notNull(query, "Query must not be null"); Assert.notNull(entityClass, "Entity type must not be null"); - return select(getStatementFactory().select(query, getRequiredPersistentEntity(entityClass)).build(), entityClass); + return select(getStatementFactory().select(query, getRequiredPersistentEntity(entityClass)) + .build(), entityClass); } /* (non-Javadoc) @@ -448,7 +448,8 @@ public class AsyncCassandraTemplate Assert.notNull(entityConsumer, "Entity Consumer must not be empty"); Assert.notNull(entityClass, "Entity type must not be null"); - return select(getStatementFactory().select(query, getRequiredPersistentEntity(entityClass)).build(), entityConsumer, + return select(getStatementFactory().select(query, getRequiredPersistentEntity(entityClass)) + .build(), entityConsumer, entityClass); } @@ -461,7 +462,8 @@ public class AsyncCassandraTemplate Assert.notNull(query, "Query must not be null"); Assert.notNull(entityClass, "Entity type must not be null"); - return selectOne(getStatementFactory().select(query, getRequiredPersistentEntity(entityClass)).build(), + return selectOne(getStatementFactory().select(query, getRequiredPersistentEntity(entityClass)) + .build(), entityClass); } @@ -474,7 +476,8 @@ public class AsyncCassandraTemplate Assert.notNull(query, "Query must not be null"); Assert.notNull(entityClass, "Entity type must not be null"); - return slice(getStatementFactory().select(query, getRequiredPersistentEntity(entityClass)).build(), entityClass); + return slice(getStatementFactory().select(query, getRequiredPersistentEntity(entityClass)) + .build(), entityClass); } /* (non-Javadoc) @@ -488,7 +491,8 @@ public class AsyncCassandraTemplate Assert.notNull(update, "Update must not be null"); Assert.notNull(entityClass, "Entity type must not be null"); - return doExecute(getStatementFactory().update(query, update, getRequiredPersistentEntity(entityClass)).build(), + return doExecute(getStatementFactory().update(query, update, getRequiredPersistentEntity(entityClass)) + .build(), AsyncResultSet::wasApplied); } @@ -514,7 +518,8 @@ public class AsyncCassandraTemplate ListenableFuture future = doExecute(delete, AsyncResultSet::wasApplied); - future.addCallback(success -> maybeEmitEvent(new AfterDeleteEvent<>(delete, entityClass, tableName)), e -> {}); + future.addCallback(success -> maybeEmitEvent(new AfterDeleteEvent<>(delete, entityClass, tableName)), e -> { + }); return future; } @@ -557,7 +562,8 @@ public class AsyncCassandraTemplate SingleColumnRowMapper mapper = SingleColumnRowMapper.newInstance(Long.class); - Row row = DataAccessUtils.requiredSingleResult(Streamable.of(it.currentPage()).toList()); + Row row = DataAccessUtils.requiredSingleResult(Streamable.of(it.currentPage()) + .toList()); return mapper.mapRow(row, 0); }); @@ -640,7 +646,7 @@ public class AsyncCassandraTemplate getConverter().getConversionService()); CassandraPersistentEntity persistentEntity = getRequiredPersistentEntity(entity.getClass()); - T entityToUse = source.isVersionedEntity() ? source.initializeVersionProperty() : entity; + T entityToUse = source.isVersionedEntity() ? source.initializeVersionProperty() : source.getBean(); StatementBuilder builder = getStatementFactory().insert(entityToUse, options, persistentEntity, tableName); @@ -760,7 +766,8 @@ public class AsyncCassandraTemplate StatementBuilder delete = getStatementFactory().delete(entity, options, getConverter(), tableName); ; - return executeDelete(entity, tableName, source.appendVersionCondition(delete).build(), result -> { + return executeDelete(entity, tableName, source.appendVersionCondition(delete) + .build(), result -> { if (!result.wasApplied()) { throw new OptimisticLockingFailureException( @@ -774,7 +781,8 @@ public class AsyncCassandraTemplate StatementBuilder delete = getStatementFactory().delete(entity, options, getConverter(), tableName); - return executeDelete(entity, tableName, delete.build(), result -> {}); + return executeDelete(entity, tableName, delete.build(), result -> { + }); } /* (non-Javadoc) @@ -795,7 +803,8 @@ public class AsyncCassandraTemplate maybeEmitEvent(new BeforeDeleteEvent<>(delete, entityClass, tableName)); ListenableFuture future = doExecute(delete, AsyncResultSet::wasApplied); - future.addCallback(success -> maybeEmitEvent(new AfterDeleteEvent<>(delete, entityClass, tableName)), e -> {}); + future.addCallback(success -> maybeEmitEvent(new AfterDeleteEvent<>(delete, entityClass, tableName)), e -> { + }); return future; } @@ -815,7 +824,8 @@ public class AsyncCassandraTemplate maybeEmitEvent(new BeforeDeleteEvent<>(statement, entityClass, tableName)); ListenableFuture future = doExecute(statement, AsyncResultSet::wasApplied); - future.addCallback(success -> maybeEmitEvent(new AfterDeleteEvent<>(statement, entityClass, tableName)), e -> {}); + future.addCallback(success -> maybeEmitEvent(new AfterDeleteEvent<>(statement, entityClass, tableName)), e -> { + }); return new MappingListenableFutureAdapter<>(future, aBoolean -> null); } @@ -840,7 +850,8 @@ public class AsyncCassandraTemplate private ListenableFuture> executeSave(T entity, CqlIdentifier tableName, SimpleStatement statement) { - return executeSave(entity, tableName, statement, ignore -> {}); + return executeSave(entity, tableName, statement, ignore -> { + }); } private ListenableFuture> executeSave(T entity, CqlIdentifier tableName, @@ -924,11 +935,13 @@ public class AsyncCassandraTemplate } private static List getFirstPage(AsyncResultSet resultSet) { - return StreamSupport.stream(resultSet.currentPage().spliterator(), false).collect(Collectors.toList()); + return StreamSupport.stream(resultSet.currentPage().spliterator(), false) + .collect(Collectors.toList()); } private static int getConfiguredPageSize(CqlSession session) { - return session.getContext().getConfig().getDefaultProfile().getInt(DefaultDriverOption.REQUEST_PAGE_SIZE, 5000); + return session.getContext().getConfig().getDefaultProfile() + .getInt(DefaultDriverOption.REQUEST_PAGE_SIZE, 5000); } private int getEffectivePageSize(Statement statement) { diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/CassandraTemplate.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/CassandraTemplate.java index 0faf5cd93..b7b01acff 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/CassandraTemplate.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/CassandraTemplate.java @@ -20,6 +20,24 @@ import java.util.function.Consumer; import java.util.function.Function; import java.util.stream.Stream; +import com.datastax.oss.driver.api.core.CqlIdentifier; +import com.datastax.oss.driver.api.core.CqlSession; +import com.datastax.oss.driver.api.core.DriverException; +import com.datastax.oss.driver.api.core.config.DefaultDriverOption; +import com.datastax.oss.driver.api.core.cql.BatchType; +import com.datastax.oss.driver.api.core.cql.BoundStatement; +import com.datastax.oss.driver.api.core.cql.PreparedStatement; +import com.datastax.oss.driver.api.core.cql.ResultSet; +import com.datastax.oss.driver.api.core.cql.Row; +import com.datastax.oss.driver.api.core.cql.SimpleStatement; +import com.datastax.oss.driver.api.core.cql.Statement; +import com.datastax.oss.driver.api.querybuilder.QueryBuilder; +import com.datastax.oss.driver.api.querybuilder.delete.Delete; +import com.datastax.oss.driver.api.querybuilder.insert.Insert; +import com.datastax.oss.driver.api.querybuilder.insert.RegularInsert; +import com.datastax.oss.driver.api.querybuilder.select.Select; +import com.datastax.oss.driver.api.querybuilder.truncate.Truncate; +import com.datastax.oss.driver.api.querybuilder.update.Update; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -61,25 +79,6 @@ import org.springframework.data.projection.SpelAwareProxyProjectionFactory; import org.springframework.lang.Nullable; import org.springframework.util.Assert; -import com.datastax.oss.driver.api.core.CqlIdentifier; -import com.datastax.oss.driver.api.core.CqlSession; -import com.datastax.oss.driver.api.core.DriverException; -import com.datastax.oss.driver.api.core.config.DefaultDriverOption; -import com.datastax.oss.driver.api.core.cql.BatchType; -import com.datastax.oss.driver.api.core.cql.BoundStatement; -import com.datastax.oss.driver.api.core.cql.PreparedStatement; -import com.datastax.oss.driver.api.core.cql.ResultSet; -import com.datastax.oss.driver.api.core.cql.Row; -import com.datastax.oss.driver.api.core.cql.SimpleStatement; -import com.datastax.oss.driver.api.core.cql.Statement; -import com.datastax.oss.driver.api.querybuilder.QueryBuilder; -import com.datastax.oss.driver.api.querybuilder.delete.Delete; -import com.datastax.oss.driver.api.querybuilder.insert.Insert; -import com.datastax.oss.driver.api.querybuilder.insert.RegularInsert; -import com.datastax.oss.driver.api.querybuilder.select.Select; -import com.datastax.oss.driver.api.querybuilder.truncate.Truncate; -import com.datastax.oss.driver.api.querybuilder.update.Update; - /** * Primary implementation of {@link CassandraOperations}. It simplifies the use of Cassandra usage and helps to avoid * common errors. It executes core Cassandra workflow. This class executes CQL queries or updates, initiating iteration @@ -670,7 +669,7 @@ public class CassandraTemplate implements CassandraOperations, ApplicationEventP AdaptibleEntity source = getEntityOperations().forEntity(maybeCallBeforeConvert(entity, tableName), getConverter().getConversionService()); - T entityToUse = source.isVersionedEntity() ? source.initializeVersionProperty() : entity; + T entityToUse = source.isVersionedEntity() ? source.initializeVersionProperty() : source.getBean(); StatementBuilder builder = getStatementFactory().insert(entityToUse, options, source.getPersistentEntity(), tableName); @@ -737,7 +736,8 @@ public class CassandraTemplate implements CassandraOperations, ApplicationEventP T toSave = source.incrementVersion(); StatementBuilder builder = getStatementFactory().update(toSave, options, persistentEntity, tableName); - SimpleStatement update = source.appendVersionCondition(builder, previousVersion).build(); + SimpleStatement update = source.appendVersionCondition(builder, previousVersion) + .build(); return executeSave(toSave, tableName, update, result -> { @@ -781,7 +781,8 @@ public class CassandraTemplate implements CassandraOperations, ApplicationEventP StatementBuilder builder = getStatementFactory().delete(entity, options, getConverter(), tableName); return source.isVersionedEntity() - ? doDeleteVersioned(source.appendVersionCondition(builder).build(), entity, source, tableName) + ? doDeleteVersioned(source.appendVersionCondition(builder) + .build(), entity, source, tableName) : doDelete(builder.build(), entity, tableName); } @@ -800,7 +801,8 @@ public class CassandraTemplate implements CassandraOperations, ApplicationEventP } private WriteResult doDelete(SimpleStatement delete, Object entity, CqlIdentifier tableName) { - return executeDelete(entity, tableName, delete, result -> {}); + return executeDelete(entity, tableName, delete, result -> { + }); } /* (non-Javadoc) @@ -900,7 +902,8 @@ public class CassandraTemplate implements CassandraOperations, ApplicationEventP } private EntityWriteResult executeSave(T entity, CqlIdentifier tableName, SimpleStatement statement) { - return executeSave(entity, tableName, statement, ignore -> {}); + return executeSave(entity, tableName, statement, ignore -> { + }); } private EntityWriteResult executeSave(T entity, CqlIdentifier tableName, SimpleStatement statement, @@ -977,7 +980,8 @@ public class CassandraTemplate implements CassandraOperations, ApplicationEventP } private int getConfiguredPageSize(CqlSession session) { - return session.getContext().getConfig().getDefaultProfile().getInt(DefaultDriverOption.REQUEST_PAGE_SIZE, 5000); + return session.getContext().getConfig().getDefaultProfile() + .getInt(DefaultDriverOption.REQUEST_PAGE_SIZE, 5000); } @SuppressWarnings("ConstantConditions") diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/AsyncCassandraTemplateUnitTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/AsyncCassandraTemplateUnitTests.java index 1bd12cc56..ed9a180c3 100644 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/AsyncCassandraTemplateUnitTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/AsyncCassandraTemplateUnitTests.java @@ -15,11 +15,6 @@ */ package org.springframework.data.cassandra.core; -import static org.assertj.core.api.Assertions.*; -import static org.mockito.ArgumentMatchers.*; -import static org.mockito.Mockito.*; -import static org.springframework.data.cassandra.core.query.Criteria.*; - import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -27,6 +22,19 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; +import com.datastax.oss.driver.api.core.CqlIdentifier; +import com.datastax.oss.driver.api.core.CqlSession; +import com.datastax.oss.driver.api.core.NoNodeAvailableException; +import com.datastax.oss.driver.api.core.context.DriverContext; +import com.datastax.oss.driver.api.core.cql.AsyncResultSet; +import com.datastax.oss.driver.api.core.cql.ColumnDefinition; +import com.datastax.oss.driver.api.core.cql.ColumnDefinitions; +import com.datastax.oss.driver.api.core.cql.Row; +import com.datastax.oss.driver.api.core.cql.SimpleStatement; +import com.datastax.oss.driver.api.core.cql.Statement; +import com.datastax.oss.driver.api.core.type.DataTypes; +import com.datastax.oss.driver.api.core.type.codec.registry.CodecRegistry; +import com.datastax.oss.driver.internal.core.type.codec.registry.DefaultCodecRegistry; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -48,19 +56,10 @@ import org.springframework.data.cassandra.domain.VersionedUser; import org.springframework.data.mapping.callback.EntityCallbacks; import org.springframework.util.concurrent.ListenableFuture; -import com.datastax.oss.driver.api.core.CqlIdentifier; -import com.datastax.oss.driver.api.core.CqlSession; -import com.datastax.oss.driver.api.core.NoNodeAvailableException; -import com.datastax.oss.driver.api.core.context.DriverContext; -import com.datastax.oss.driver.api.core.cql.AsyncResultSet; -import com.datastax.oss.driver.api.core.cql.ColumnDefinition; -import com.datastax.oss.driver.api.core.cql.ColumnDefinitions; -import com.datastax.oss.driver.api.core.cql.Row; -import com.datastax.oss.driver.api.core.cql.SimpleStatement; -import com.datastax.oss.driver.api.core.cql.Statement; -import com.datastax.oss.driver.api.core.type.DataTypes; -import com.datastax.oss.driver.api.core.type.codec.registry.CodecRegistry; -import com.datastax.oss.driver.internal.core.type.codec.registry.DefaultCodecRegistry; +import static org.assertj.core.api.Assertions.*; +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.*; +import static org.springframework.data.cassandra.core.query.Criteria.*; /** * Unit tests for {@link AsyncCassandraTemplate}. @@ -326,7 +325,28 @@ class AsyncCassandraTemplateUnitTests { assertThat(beforeSave).isSameAs(user); } - @Test // DATACASS-618 + @Test + // GH-1295 + void insertShouldConsiderEntityAfterCallback() { + + when(resultSet.wasApplied()).thenReturn(true); + + User user = new User("heisenberg", "Walter", "White"); + + EntityCallbacks callbacks = EntityCallbacks.create(); + callbacks.addEntityCallback((BeforeConvertCallback) (entity, tableName) -> new User("ww", "Walter", "White")); + template.setEntityCallbacks(callbacks); + + ListenableFuture future = template.insert(user); + + assertThat(getUninterruptibly(future)).isNotSameAs(user); + verify(session).executeAsync(statementCaptor.capture()); + assertThat(render(statementCaptor.getValue())) + .isEqualTo("INSERT INTO users (firstname,id,lastname) VALUES ('Walter','ww','White')"); + } + + @Test + // DATACASS-618 void insertShouldInsertVersionedEntity() { when(resultSet.wasApplied()).thenReturn(true); diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/CassandraTemplateUnitTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/CassandraTemplateUnitTests.java index d28a346eb..68f761770 100644 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/CassandraTemplateUnitTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/CassandraTemplateUnitTests.java @@ -15,14 +15,22 @@ */ package org.springframework.data.cassandra.core; -import static org.assertj.core.api.Assertions.*; -import static org.mockito.ArgumentMatchers.*; -import static org.mockito.Mockito.*; -import static org.springframework.data.cassandra.core.query.Criteria.*; - import java.util.Collections; import java.util.List; +import com.datastax.oss.driver.api.core.CqlIdentifier; +import com.datastax.oss.driver.api.core.CqlSession; +import com.datastax.oss.driver.api.core.NoNodeAvailableException; +import com.datastax.oss.driver.api.core.context.DriverContext; +import com.datastax.oss.driver.api.core.cql.ColumnDefinition; +import com.datastax.oss.driver.api.core.cql.ColumnDefinitions; +import com.datastax.oss.driver.api.core.cql.ResultSet; +import com.datastax.oss.driver.api.core.cql.Row; +import com.datastax.oss.driver.api.core.cql.SimpleStatement; +import com.datastax.oss.driver.api.core.cql.Statement; +import com.datastax.oss.driver.api.core.type.DataTypes; +import com.datastax.oss.driver.api.core.type.codec.registry.CodecRegistry; +import com.datastax.oss.driver.internal.core.type.codec.registry.DefaultCodecRegistry; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -43,19 +51,10 @@ import org.springframework.data.cassandra.domain.User; import org.springframework.data.cassandra.domain.VersionedUser; import org.springframework.data.mapping.callback.EntityCallbacks; -import com.datastax.oss.driver.api.core.CqlIdentifier; -import com.datastax.oss.driver.api.core.CqlSession; -import com.datastax.oss.driver.api.core.NoNodeAvailableException; -import com.datastax.oss.driver.api.core.context.DriverContext; -import com.datastax.oss.driver.api.core.cql.ColumnDefinition; -import com.datastax.oss.driver.api.core.cql.ColumnDefinitions; -import com.datastax.oss.driver.api.core.cql.ResultSet; -import com.datastax.oss.driver.api.core.cql.Row; -import com.datastax.oss.driver.api.core.cql.SimpleStatement; -import com.datastax.oss.driver.api.core.cql.Statement; -import com.datastax.oss.driver.api.core.type.DataTypes; -import com.datastax.oss.driver.api.core.type.codec.registry.CodecRegistry; -import com.datastax.oss.driver.internal.core.type.codec.registry.DefaultCodecRegistry; +import static org.assertj.core.api.Assertions.*; +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.*; +import static org.springframework.data.cassandra.core.query.Criteria.*; /** * Unit tests for {@link CassandraTemplate}. @@ -307,7 +306,27 @@ class CassandraTemplateUnitTests { assertThat(beforeSave).isSameAs(user); } - @Test // DATACASS-618 + @Test + // GH-1295 + void insertShouldConsiderEntityAfterCallback() { + + when(resultSet.wasApplied()).thenReturn(true); + + User user = new User("heisenberg", "Walter", "White"); + + EntityCallbacks callbacks = EntityCallbacks.create(); + callbacks.addEntityCallback((BeforeConvertCallback) (entity, tableName) -> new User("ww", "Walter", "White")); + template.setEntityCallbacks(callbacks); + + template.insert(user); + + verify(session).execute(statementCaptor.capture()); + assertThat(render(statementCaptor.getValue())) + .isEqualTo("INSERT INTO users (firstname,id,lastname) VALUES ('Walter','ww','White')"); + } + + @Test + // DATACASS-618 void insertShouldInsertVersionedEntity() { when(resultSet.wasApplied()).thenReturn(true); @@ -323,7 +342,27 @@ class CassandraTemplateUnitTests { assertThat(beforeSave).isSameAs(user); } - @Test // DATACASS-250 + @Test + // GH-1295 + void insertShouldInsertVersionedEntityAfterCallback() { + + when(resultSet.wasApplied()).thenReturn(true); + + VersionedUser user = new VersionedUser("heisenberg", "Walter", "White"); + + EntityCallbacks callbacks = EntityCallbacks.create(); + callbacks.addEntityCallback((BeforeConvertCallback) (entity, tableName) -> new VersionedUser("ww", "Walter", "White")); + template.setEntityCallbacks(callbacks); + + template.insert(user); + + verify(session).execute(statementCaptor.capture()); + assertThat(render(statementCaptor.getValue())).isEqualTo( + "INSERT INTO vusers (firstname,id,lastname,version) VALUES ('Walter','ww','White',0) IF NOT EXISTS"); + } + + @Test + // DATACASS-250 void insertShouldInsertWithOptionsEntity() { InsertOptions insertOptions = InsertOptions.builder().withIfNotExists().build();