From d108bc9fed74a66ae6a444772efe558b13bc6340 Mon Sep 17 00:00:00 2001 From: Oliver Gierke Date: Fri, 21 Jan 2011 01:50:43 +0100 Subject: [PATCH] DATAJPA-13 - findOne(Specification s) now returns null if there is no result. I chose not to return the arbitrary first result in case the Specification returns more than one result. First, there's no way to influence the order of the results so that we potentially get different results for the very same call. Beyond that this aligns with the semantics we have for finder methods that are supposed to return a single entity but actually don't. --- .../support/SimpleJpaRepository.java | 7 ++++++- .../jpa/domain/sample/UserSpecifications.java | 21 +++++++++++++++++++ .../jpa/repository/UserRepositoryTests.java | 19 +++++++++++++++++ 3 files changed, 46 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/springframework/data/jpa/repository/support/SimpleJpaRepository.java b/src/main/java/org/springframework/data/jpa/repository/support/SimpleJpaRepository.java index 04fdc5e19..a3a83774f 100644 --- a/src/main/java/org/springframework/data/jpa/repository/support/SimpleJpaRepository.java +++ b/src/main/java/org/springframework/data/jpa/repository/support/SimpleJpaRepository.java @@ -22,6 +22,7 @@ import java.util.ArrayList; import java.util.List; import javax.persistence.EntityManager; +import javax.persistence.NoResultException; import javax.persistence.TypedQuery; import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.CriteriaQuery; @@ -222,7 +223,11 @@ public class SimpleJpaRepository extends */ public T findOne(Specification spec) { - return getQuery(spec, (Sort) null).getSingleResult(); + try { + return getQuery(spec, (Sort) null).getSingleResult(); + } catch (NoResultException e) { + return null; + } } diff --git a/src/test/java/org/springframework/data/jpa/domain/sample/UserSpecifications.java b/src/test/java/org/springframework/data/jpa/domain/sample/UserSpecifications.java index 74afb650b..2fcb8474c 100644 --- a/src/test/java/org/springframework/data/jpa/domain/sample/UserSpecifications.java +++ b/src/test/java/org/springframework/data/jpa/domain/sample/UserSpecifications.java @@ -54,6 +54,27 @@ public class UserSpecifications { } + /** + * A {@link Specification} to do a like-match on a {@link User}'s firstname. + * + * @param firstname + * @return + */ + public static Specification userHasFirstnameLike( + final String expression) { + + return new Specification() { + + public Predicate toPredicate(Root root, + CriteriaQuery query, CriteriaBuilder cb) { + + return cb.like(root.get("firstname").as(String.class), + String.format("%%%s%%", expression)); + } + }; + } + + private static Specification simplePropertySpec( final String property, final Object value) { diff --git a/src/test/java/org/springframework/data/jpa/repository/UserRepositoryTests.java b/src/test/java/org/springframework/data/jpa/repository/UserRepositoryTests.java index cc31e9149..fa2f9bd51 100644 --- a/src/test/java/org/springframework/data/jpa/repository/UserRepositoryTests.java +++ b/src/test/java/org/springframework/data/jpa/repository/UserRepositoryTests.java @@ -37,6 +37,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.dao.DataAccessException; +import org.springframework.dao.IncorrectResultSizeDataAccessException; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.PageRequest; @@ -469,6 +470,24 @@ public class UserRepositoryTests { } + @Test + public void returnsNullIfNoEntityFoundForSingleEntitySpecification() + throws Exception { + + flushTestUsers(); + assertThat(repository.findOne(userHasLastname("Beauford")), + is(nullValue())); + } + + + @Test(expected = IncorrectResultSizeDataAccessException.class) + public void throwsExceptionForUnderSpecifiedSingleEntitySpecification() { + + flushTestUsers(); + repository.findOne(userHasFirstnameLike("e")); + } + + @Test public void executesCombinedSpecificationsCorrectly() {