From b9282c8d32c95e96d25b3c3e0b29920615779dcb Mon Sep 17 00:00:00 2001 From: Christoph Strobl Date: Thu, 29 Jun 2017 22:12:31 +0200 Subject: [PATCH] DATAMONGO-1726 - Add oneValue() and firstValue() to FluentMongoOperations returning nullable types. We leave the choice of using Optional open by also providing terminating find operation methods that return null instead of Optional. Original pull request: #475. --- .../mongodb/core/ExecutableFindOperation.java | 23 ++++++++++++++++-- .../core/ExecutableFindOperationSupport.java | 10 ++++---- .../ExecutableFindOperationSupportTests.java | 24 +++++++++++++++++++ 3 files changed, 50 insertions(+), 7 deletions(-) diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ExecutableFindOperation.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ExecutableFindOperation.java index 43156f3fa..c7c94eed8 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ExecutableFindOperation.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ExecutableFindOperation.java @@ -73,14 +73,33 @@ public interface ExecutableFindOperation { * @return {@link Optional#empty()} if no match found. * @throws org.springframework.dao.IncorrectResultSizeDataAccessException if more than one match found. */ - Optional one(); + default Optional one() { + return Optional.ofNullable(oneValue()); + } + + /** + * Get exactly zero or one result. + * + * @return {@literal null} if no match found. + * @throws org.springframework.dao.IncorrectResultSizeDataAccessException if more than one match found. + */ + T oneValue(); /** * Get the first or no result. * * @return {@link Optional#empty()} if no match found. */ - Optional first(); + default Optional first() { + return Optional.ofNullable(firstValue()); + } + + /** + * Get the first or no result. + * + * @return {@literal null} if no match found. + */ + T firstValue(); /** * Get all matching elements. diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ExecutableFindOperationSupport.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ExecutableFindOperationSupport.java index 3057b3899..2c54a4b53 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ExecutableFindOperationSupport.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/ExecutableFindOperationSupport.java @@ -104,27 +104,27 @@ class ExecutableFindOperationSupport implements ExecutableFindOperation { } @Override - public Optional one() { + public T oneValue() { List result = doFind(new DelegatingQueryCursorPreparer(getCursorPreparer(query, null)).limit(2)); if (ObjectUtils.isEmpty(result)) { - return Optional.empty(); + return null; } if (result.size() > 1) { throw new IncorrectResultSizeDataAccessException("Query " + asString() + " returned non unique result.", 1); } - return Optional.of(result.iterator().next()); + return result.iterator().next(); } @Override - public Optional first() { + public T firstValue() { List result = doFind(new DelegatingQueryCursorPreparer(getCursorPreparer(query, null)).limit(1)); - return ObjectUtils.isEmpty(result) ? Optional.empty() : Optional.of(result.iterator().next()); + return ObjectUtils.isEmpty(result) ? null : result.iterator().next(); } @Override diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ExecutableFindOperationSupportTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ExecutableFindOperationSupportTests.java index 79cbc1042..44ed9d138 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ExecutableFindOperationSupportTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/ExecutableFindOperationSupportTests.java @@ -140,6 +140,30 @@ public class ExecutableFindOperationSupportTests { template.query(Person.class).matching(query(where("firstname").in("han", "luke"))).one(); } + @Test // DATAMONGO-1726 + public void findByReturningOneValue() { + assertThat(template.query(Person.class).matching(query(where("firstname").is("luke"))).oneValue()).isEqualTo(luke); + } + + @Test(expected = IncorrectResultSizeDataAccessException.class) // DATAMONGO-1726 + public void findByReturningOneValueButTooManyResults() { + template.query(Person.class).matching(query(where("firstname").in("han", "luke"))).oneValue(); + } + + @Test // DATAMONGO-1726 + public void findByReturningFirstValue() { + + assertThat(template.query(Person.class).matching(query(where("firstname").is("luke"))).firstValue()) + .isEqualTo(luke); + } + + @Test // DATAMONGO-1726 + public void findByReturningFirstValueForManyResults() { + + assertThat(template.query(Person.class).matching(query(where("firstname").in("han", "luke"))).firstValue()) + .isIn(han, luke); + } + @Test // DATAMONGO-1563 public void streamAll() {