diff --git a/src/docbkx/reference/jpa.xml b/src/docbkx/reference/jpa.xml index 5d1988cc1..2569e9280 100644 --- a/src/docbkx/reference/jpa.xml +++ b/src/docbkx/reference/jpa.xml @@ -179,7 +179,7 @@ findByAgeOrderByLastnameDesc - … where x.age > ?1 order by x.lastname + … where x.age = ?1 order by x.lastname desc diff --git a/src/main/java/org/springframework/data/jpa/repository/query/JpaCountQueryCreator.java b/src/main/java/org/springframework/data/jpa/repository/query/JpaCountQueryCreator.java index eae9b6415..9ab545177 100644 --- a/src/main/java/org/springframework/data/jpa/repository/query/JpaCountQueryCreator.java +++ b/src/main/java/org/springframework/data/jpa/repository/query/JpaCountQueryCreator.java @@ -19,9 +19,10 @@ import javax.persistence.EntityManager; import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.CriteriaQuery; import javax.persistence.criteria.Predicate; +import javax.persistence.criteria.Root; import org.springframework.data.domain.Sort; -import org.springframework.data.repository.query.SimpleParameterAccessor; +import org.springframework.data.repository.query.ParameterAccessor; import org.springframework.data.repository.query.parser.PartTree; @@ -32,9 +33,6 @@ import org.springframework.data.repository.query.parser.PartTree; */ public class JpaCountQueryCreator extends JpaQueryCreator { - private final Class domainClass; - - /** * Creates a new {@link JpaCountQueryCreator}. * @@ -43,12 +41,10 @@ public class JpaCountQueryCreator extends JpaQueryCreator { * @param domainClass * @param em */ - public JpaCountQueryCreator(PartTree tree, - SimpleParameterAccessor parameters, Class domainClass, - EntityManager em) { + public JpaCountQueryCreator(PartTree tree, ParameterAccessor parameters, + Class domainClass, EntityManager em) { super(tree, parameters, domainClass, em); - this.domainClass = domainClass; } @@ -56,16 +52,17 @@ public class JpaCountQueryCreator extends JpaQueryCreator { * (non-Javadoc) * * @see - * org.springframework.data.jpa.repository.query.JpaQueryCreator#finalize + * org.springframework.data.jpa.repository.query.JpaQueryCreator#complete * (javax.persistence.criteria.Predicate, * org.springframework.data.domain.Sort, * javax.persistence.criteria.CriteriaQuery, - * javax.persistence.criteria.CriteriaBuilder) + * javax.persistence.criteria.CriteriaBuilder, + * javax.persistence.criteria.Root) */ @Override protected CriteriaQuery complete(Predicate predicate, Sort sort, - CriteriaQuery query, CriteriaBuilder builder) { + CriteriaQuery query, CriteriaBuilder builder, Root root) { - return query.select(builder.count(query.from(domainClass))); + return query.select(builder.count(root)); } } diff --git a/src/main/java/org/springframework/data/jpa/repository/query/JpaQueryCreator.java b/src/main/java/org/springframework/data/jpa/repository/query/JpaQueryCreator.java index 22204709d..8cad04872 100644 --- a/src/main/java/org/springframework/data/jpa/repository/query/JpaQueryCreator.java +++ b/src/main/java/org/springframework/data/jpa/repository/query/JpaQueryCreator.java @@ -15,6 +15,8 @@ */ package org.springframework.data.jpa.repository.query; +import java.util.Iterator; + import javax.persistence.EntityManager; import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.CriteriaQuery; @@ -26,8 +28,7 @@ import javax.persistence.criteria.Predicate; import javax.persistence.criteria.Root; import org.springframework.data.domain.Sort; -import org.springframework.data.repository.query.SimpleParameterAccessor; -import org.springframework.data.repository.query.SimpleParameterAccessor.BindableParameterIterator; +import org.springframework.data.repository.query.ParameterAccessor; import org.springframework.data.repository.query.parser.AbstractQueryCreator; import org.springframework.data.repository.query.parser.Part; import org.springframework.data.repository.query.parser.PartTree; @@ -56,7 +57,7 @@ public class JpaQueryCreator extends * @param domainClass * @param em */ - public JpaQueryCreator(PartTree tree, SimpleParameterAccessor parameters, + public JpaQueryCreator(PartTree tree, ParameterAccessor parameters, Class domainClass, EntityManager em) { super(tree, parameters); @@ -73,11 +74,10 @@ public class JpaQueryCreator extends * @see * org.springframework.data.repository.query.parser.AbstractQueryCreator * #create(org.springframework.data.repository.query.parser.Part, - * org.springframework - * .data.repository.query.SimpleParameterAccessor.BindableParameterIterator) + * java.util.Iterator) */ @Override - protected Predicate create(Part part, BindableParameterIterator iterator) { + protected Predicate create(Part part, Iterator iterator) { return toPredicate(part, root, iterator); } @@ -89,13 +89,10 @@ public class JpaQueryCreator extends * @see * org.springframework.data.repository.query.parser.AbstractQueryCreator * #and(org.springframework.data.repository.query.parser.Part, - * java.lang.Object, - * org.springframework.data.repository.query.SimpleParameterAccessor - * .BindableParameterIterator) + * java.lang.Object, java.util.Iterator) */ @Override - protected Predicate and(Part part, Predicate base, - BindableParameterIterator iterator) { + protected Predicate and(Part part, Predicate base, Iterator iterator) { return builder.and(base, toPredicate(part, root, iterator)); } @@ -125,7 +122,7 @@ public class JpaQueryCreator extends protected final CriteriaQuery complete(Predicate predicate, Sort sort) { - return complete(predicate, sort, query, builder); + return complete(predicate, sort, query, builder, root); } @@ -140,7 +137,7 @@ public class JpaQueryCreator extends * @return */ protected CriteriaQuery complete(Predicate predicate, Sort sort, - CriteriaQuery query, CriteriaBuilder builder) { + CriteriaQuery query, CriteriaBuilder builder, Root root) { return this.query.select(root).where(predicate) .orderBy(QueryUtils.toOrders(sort, root, builder)); @@ -157,7 +154,7 @@ public class JpaQueryCreator extends */ @SuppressWarnings({ "unchecked", "rawtypes" }) private Predicate toPredicate(Part part, Root root, - BindableParameterIterator iterator) { + Iterator iterator) { Expression path = toExpressionRecursively(root, part.getProperty()); @@ -175,9 +172,9 @@ public class JpaQueryCreator extends return builder.lessThan(getComparablePath(root, part), nextAsComparable(iterator)); case IS_NULL: - return root.isNull(); + return path.isNull(); case IS_NOT_NULL: - return root.isNotNull(); + return path.isNotNull(); case LIKE: return builder.like(root. get(part.getProperty() .toDotPath()), iterator.next().toString()); @@ -236,15 +233,14 @@ public class JpaQueryCreator extends /** - * Returns the next parameter from the given - * {@link BindableParameterIterator} and expects it to be a - * {@link Comparable}. + * Returns the next parameter from the given {@link Iterator} and expects it + * to be a {@link Comparable}. * * @param iterator * @return */ @SuppressWarnings("rawtypes") - private Comparable nextAsComparable(BindableParameterIterator iterator) { + private Comparable nextAsComparable(Iterator iterator) { Object next = iterator.next(); Assert.isInstanceOf(Comparable.class, next, diff --git a/src/main/java/org/springframework/data/jpa/repository/query/JpaQueryExecution.java b/src/main/java/org/springframework/data/jpa/repository/query/JpaQueryExecution.java index 40b4e95c1..154186ac4 100644 --- a/src/main/java/org/springframework/data/jpa/repository/query/JpaQueryExecution.java +++ b/src/main/java/org/springframework/data/jpa/repository/query/JpaQueryExecution.java @@ -23,9 +23,10 @@ import javax.persistence.Query; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; +import org.springframework.data.repository.query.ParameterAccessor; import org.springframework.data.repository.query.Parameters; +import org.springframework.data.repository.query.ParametersParameterAccessor; import org.springframework.data.repository.query.QueryMethod; -import org.springframework.data.repository.query.SimpleParameterAccessor; import org.springframework.util.Assert; @@ -163,8 +164,8 @@ public abstract class JpaQueryExecution { @SuppressWarnings("unchecked") protected Object doExecute(PartTreeJpaQuery query, Object[] parameters) { - SimpleParameterAccessor accessor = - new SimpleParameterAccessor(this.parameters, parameters); + ParameterAccessor accessor = + new ParametersParameterAccessor(this.parameters, parameters); Query countQuery = query.createCountQuery(parameters); Long total = (Long) countQuery.getSingleResult(); diff --git a/src/main/java/org/springframework/data/jpa/repository/query/PartTreeJpaQuery.java b/src/main/java/org/springframework/data/jpa/repository/query/PartTreeJpaQuery.java index 99947a945..a55edc949 100644 --- a/src/main/java/org/springframework/data/jpa/repository/query/PartTreeJpaQuery.java +++ b/src/main/java/org/springframework/data/jpa/repository/query/PartTreeJpaQuery.java @@ -21,7 +21,8 @@ import javax.persistence.TypedQuery; import javax.persistence.criteria.CriteriaQuery; import org.springframework.data.domain.Pageable; -import org.springframework.data.repository.query.SimpleParameterAccessor; +import org.springframework.data.repository.query.ParameterAccessor; +import org.springframework.data.repository.query.ParametersParameterAccessor; import org.springframework.data.repository.query.parser.PartTree; @@ -61,8 +62,8 @@ public class PartTreeJpaQuery extends AbstractJpaQuery { */ public Query createQuery(Object[] parameters) { - SimpleParameterAccessor accessor = - new SimpleParameterAccessor(getParameters(), parameters); + ParameterAccessor accessor = + new ParametersParameterAccessor(getParameters(), parameters); JpaQueryCreator jpaQueryCreator = new JpaQueryCreator(tree, accessor, domainClass, @@ -89,11 +90,11 @@ public class PartTreeJpaQuery extends AbstractJpaQuery { */ public Query createCountQuery(Object[] parameters) { - CriteriaQuery createQuery = - new JpaCountQueryCreator(tree, new SimpleParameterAccessor( + CriteriaQuery query = + new JpaCountQueryCreator(tree, new ParametersParameterAccessor( getParameters(), parameters), domainClass, getEntityManager()).createQuery(); - return getEntityManager().createQuery(createQuery); + return getEntityManager().createQuery(query); } diff --git a/src/test/java/org/springframework/data/jpa/repository/UserRepositoryFinderTests.java b/src/test/java/org/springframework/data/jpa/repository/UserRepositoryFinderTests.java index 57d3749cd..93d3bdcce 100644 --- a/src/test/java/org/springframework/data/jpa/repository/UserRepositoryFinderTests.java +++ b/src/test/java/org/springframework/data/jpa/repository/UserRepositoryFinderTests.java @@ -119,7 +119,9 @@ public class UserRepositoryFinderTests { Page page = userRepository.findByFirstname(new PageRequest(0, 1), "foobar"); - assertEquals(1, page.getNumberOfElements()); + assertThat(page.getNumberOfElements(), is(1)); + assertThat(page.getTotalElements(), is(2L)); + assertThat(page.getTotalPages(), is(2)); } 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 915d0e28f..3f8aa8612 100644 --- a/src/test/java/org/springframework/data/jpa/repository/UserRepositoryTests.java +++ b/src/test/java/org/springframework/data/jpa/repository/UserRepositoryTests.java @@ -759,6 +759,31 @@ public class UserRepositoryTests { } + @Test + public void executesFindByNotNullLastnameCorrectly() throws Exception { + + flushTestUsers(); + List result = repository.findByLastnameNotNull(); + + assertThat(result.size(), is(3)); + assertThat(result, hasItems(firstUser, secondUser, thirdUser)); + } + + + @Test + public void executesFindByNullLastnameCorrectly() throws Exception { + + flushTestUsers(); + User forthUser = + repository.save(new User("Foo", null, "email@address.com")); + + List result = repository.findByLastnameNull(); + + assertThat(result.size(), is(1)); + assertThat(result, hasItems(forthUser)); + } + + private Page executeSpecWithSort(Sort sort) { flushTestUsers(); diff --git a/src/test/java/org/springframework/data/jpa/repository/sample/UserRepository.java b/src/test/java/org/springframework/data/jpa/repository/sample/UserRepository.java index 9ee513e93..eb1845ce0 100644 --- a/src/test/java/org/springframework/data/jpa/repository/sample/UserRepository.java +++ b/src/test/java/org/springframework/data/jpa/repository/sample/UserRepository.java @@ -190,4 +190,10 @@ public interface UserRepository extends JpaRepository, List findByColleaguesLastname(String lastname); + + + List findByLastnameNotNull(); + + + List findByLastnameNull(); }