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.
This commit is contained in:
@@ -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<T, ID extends Serializable> extends
|
||||
*/
|
||||
public T findOne(Specification<T> spec) {
|
||||
|
||||
return getQuery(spec, (Sort) null).getSingleResult();
|
||||
try {
|
||||
return getQuery(spec, (Sort) null).getSingleResult();
|
||||
} catch (NoResultException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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<User> userHasFirstnameLike(
|
||||
final String expression) {
|
||||
|
||||
return new Specification<User>() {
|
||||
|
||||
public Predicate toPredicate(Root<User> root,
|
||||
CriteriaQuery<?> query, CriteriaBuilder cb) {
|
||||
|
||||
return cb.like(root.get("firstname").as(String.class),
|
||||
String.format("%%%s%%", expression));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
private static <T> Specification<T> simplePropertySpec(
|
||||
final String property, final Object value) {
|
||||
|
||||
|
||||
@@ -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() {
|
||||
|
||||
|
||||
Reference in New Issue
Block a user