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() {