From 062bb106d051ae145aea3fdd15120c71251bf678 Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Mon, 28 Oct 2019 14:50:32 +0100 Subject: [PATCH] =?UTF-8?q?DATACASS-696=20-=20Fix=20return=20of=20null=20v?= =?UTF-8?q?alues=20through=20selectOne(=E2=80=A6)=20and=20event=20emission?= =?UTF-8?q?.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Null values are now correctly handled when selecting a single element. We also suppress event emission in CassandraTemplate if the loaded entity is null. --- .../data/cassandra/core/AsyncCassandraTemplate.java | 3 +-- .../data/cassandra/core/CassandraTemplate.java | 8 ++++++-- .../data/cassandra/core/ReactiveCassandraTemplate.java | 4 +++- .../core/AsyncCassandraTemplateUnitTests.java | 10 ++++++++++ .../core/CassandraTemplateIntegrationTests.java | 1 + .../cassandra/core/CassandraTemplateUnitTests.java | 10 ++++++++++ .../core/ReactiveCassandraTemplateUnitTests.java | 9 +++++++++ 7 files changed, 40 insertions(+), 5 deletions(-) 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 d32332649..6929ac224 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 @@ -350,9 +350,8 @@ public class AsyncCassandraTemplate */ @Override public ListenableFuture selectOne(Statement statement, Class entityClass) { - return new MappingListenableFutureAdapter<>(select(statement, entityClass), - list -> list.stream().findFirst().orElse(null)); + list -> list.isEmpty() ? null : list.get(0)); } /* (non-Javadoc) 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 638e8652d..b49245855 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 @@ -343,7 +343,9 @@ public class CassandraTemplate implements CassandraOperations, ApplicationEventP */ @Override public T selectOne(Statement statement, Class entityClass) { - return select(statement, entityClass).stream().findFirst().orElse(null); + + List result = select(statement, entityClass); + return result.isEmpty() ? null : result.get(0); } /* (non-Javadoc) @@ -913,7 +915,9 @@ public class CassandraTemplate implements CassandraOperations, ApplicationEventP T result = (T) (targetType.isInterface() ? getProjectionFactory().createProjection(targetType, source) : source); - maybeEmitEvent(new AfterConvertEvent<>(row, result, tableName)); + if (result != null) { + maybeEmitEvent(new AfterConvertEvent<>(row, result, tableName)); + } return result; }; diff --git a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/ReactiveCassandraTemplate.java b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/ReactiveCassandraTemplate.java index 4c1ca8efc..31abff930 100644 --- a/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/ReactiveCassandraTemplate.java +++ b/spring-data-cassandra/src/main/java/org/springframework/data/cassandra/core/ReactiveCassandraTemplate.java @@ -860,7 +860,9 @@ public class ReactiveCassandraTemplate T result = (T) (targetType.isInterface() ? getProjectionFactory().createProjection(targetType, source) : source); - maybeEmitEvent(new AfterConvertEvent<>(row, result, tableName)); + if (result != null) { + maybeEmitEvent(new AfterConvertEvent<>(row, result, tableName)); + } return result; }; 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 68ef8ee27..aeae9d386 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 @@ -213,6 +213,16 @@ public class AsyncCassandraTemplateUnitTests { assertThat(statementCaptor.getValue().toString()).isEqualTo("SELECT * FROM users WHERE id='myid';"); } + @Test // DATACASS-696 + public void selectOneShouldNull() { + + when(resultSet.iterator()).thenReturn(Collections.singleton(row).iterator()); + + ListenableFuture future = template.selectOne("SELECT id FROM users WHERE id='myid';", String.class); + + assertThat(getUninterruptibly(future)).isNull(); + } + @Test // DATACASS-292 public void existsShouldReturnExistingElement() { diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/CassandraTemplateIntegrationTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/CassandraTemplateIntegrationTests.java index 41ae60eac..f2c9daca0 100644 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/CassandraTemplateIntegrationTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/CassandraTemplateIntegrationTests.java @@ -32,6 +32,7 @@ import java.util.HashSet; import java.util.LinkedHashSet; import java.util.List; import java.util.Set; +import java.util.UUID; import java.util.stream.Collectors; import java.util.stream.Stream; 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 8c6828495..d9f10ff7a 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 @@ -158,6 +158,16 @@ public class CassandraTemplateUnitTests { assertThat(statementCaptor.getValue().toString()).isEqualTo("SELECT * FROM users WHERE id='myid';"); } + @Test // DATACASS-696 + public void selectOneShouldNull() { + + when(resultSet.iterator()).thenReturn(Collections.singleton(row).iterator()); + + String nullValue = template.selectOne("SELECT id FROM users WHERE id='myid';", String.class); + + assertThat(nullValue).isNull(); + } + @Test // DATACASS-292 public void selectOneByIdShouldReturnMappedResults() { diff --git a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/ReactiveCassandraTemplateUnitTests.java b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/ReactiveCassandraTemplateUnitTests.java index d2a64fe3a..2456b934a 100644 --- a/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/ReactiveCassandraTemplateUnitTests.java +++ b/spring-data-cassandra/src/test/java/org/springframework/data/cassandra/core/ReactiveCassandraTemplateUnitTests.java @@ -178,6 +178,15 @@ public class ReactiveCassandraTemplateUnitTests { assertThat(statementCaptor.getValue().toString()).isEqualTo("SELECT firstname FROM users LIMIT 1;"); } + @Test // DATACASS-696 + public void selectOneShouldNull() { + + when(reactiveResultSet.rows()).thenReturn(Flux.just(row)); + + template.selectOne("SELECT id FROM users WHERE id='myid';", String.class).as(StepVerifier::create) // + .verifyComplete(); + } + @Test // DATACASS-335 public void existsShouldReturnExistingElement() {