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 f1001acc9..877373c54 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 static org.springframework.data.jpa.repository.query.QueryUtils.*; + import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -25,10 +27,7 @@ import javax.persistence.EntityManager; import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.CriteriaQuery; import javax.persistence.criteria.Expression; -import javax.persistence.criteria.From; -import javax.persistence.criteria.Join; import javax.persistence.criteria.ParameterExpression; -import javax.persistence.criteria.Path; import javax.persistence.criteria.Predicate; import javax.persistence.criteria.Root; @@ -195,24 +194,6 @@ public class JpaQueryCreator extends AbstractQueryCreator, } } - private Expression toExpressionRecursively(Path path, Property property) { - - Path result = path.get(property.getName()); - return property.hasNext() ? toExpressionRecursively(result, property.next()) : result; - } - - @SuppressWarnings("unchecked") - private Expression toExpressionRecursively(From from, Property property) { - - if (property.isCollection()) { - Join join = from.join(property.getName()); - return (Expression) (property.hasNext() ? toExpressionRecursively((From) join, property.next()) : join); - } else { - Path path = from.get(property.getName()); - return (Expression) (property.hasNext() ? toExpressionRecursively(path, property.next()) : path); - } - } - /** * Returns a path to a {@link Comparable}. * diff --git a/src/main/java/org/springframework/data/jpa/repository/query/QueryUtils.java b/src/main/java/org/springframework/data/jpa/repository/query/QueryUtils.java index 249e961a8..53653220e 100644 --- a/src/main/java/org/springframework/data/jpa/repository/query/QueryUtils.java +++ b/src/main/java/org/springframework/data/jpa/repository/query/QueryUtils.java @@ -29,11 +29,14 @@ import javax.persistence.Parameter; import javax.persistence.Query; import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.Expression; +import javax.persistence.criteria.From; import javax.persistence.criteria.Join; +import javax.persistence.criteria.Path; import javax.persistence.criteria.Root; import org.springframework.data.domain.Sort; import org.springframework.data.domain.Sort.Order; +import org.springframework.data.repository.query.parser.Property; import org.springframework.util.Assert; /** @@ -244,9 +247,9 @@ public abstract class QueryUtils { /** * Turns the given {@link Sort} into {@link javax.persistence.criteria.Order}s. * - * @param sort - * @param root - * @param cb + * @param sort the {@link Sort} instance to be transformed into JPA {@link javax.persistence.criteria.Order}s. + * @param root must not be {@literal null}. + * @param cb must not be {@literal null}. * @return */ public static List toOrders(Sort sort, Root root, CriteriaBuilder cb) { @@ -257,6 +260,9 @@ public abstract class QueryUtils { return orders; } + Assert.notNull(root); + Assert.notNull(cb); + for (org.springframework.data.domain.Sort.Order order : sort) { orders.add(toJpaOrder(order, root, cb)); } @@ -267,28 +273,32 @@ public abstract class QueryUtils { /** * Creates a criteria API {@link javax.persistence.criteria.Order} from the given {@link Order}. * - * @param order - * @param root - * @param cb + * @param order the order to transform into a JPA {@link javax.persistence.criteria.Order} + * @param root the {@link Root} the {@link Order} expression is based on + * @param cb the {@link CriteriaBuilder} to build the {@link javax.persistence.criteria.Order} with * @return */ private static javax.persistence.criteria.Order toJpaOrder(Order order, Root root, CriteriaBuilder cb) { - Expression expression = null; - String pathString = order.getProperty(); - String[] pathElements = pathString.split("\\."); - int pathSize = pathElements.length; - - if (pathSize > 1) { - Join path = root.join(pathElements[0]); - for (int i = 1; i < pathSize - 1; i++) { - path = path.join(pathElements[i]); - } - expression = path.get(pathElements[pathSize - 1]); - } else { - expression = root.get(pathString); - } - + Expression expression = toExpressionRecursively(root, Property.from(order.getProperty(), root.getJavaType())); return order.isAscending() ? cb.asc(expression) : cb.desc(expression); } + + @SuppressWarnings("unchecked") + static Expression toExpressionRecursively(From from, Property property) { + + if (property.isCollection()) { + Join join = from.join(property.getName()); + return (Expression) (property.hasNext() ? toExpressionRecursively((From) join, property.next()) : join); + } else { + Path path = from.get(property.getName()); + return (Expression) (property.hasNext() ? toExpressionRecursively(path, property.next()) : path); + } + } + + static Expression toExpressionRecursively(Path path, Property property) { + + Path result = path.get(property.getName()); + return property.hasNext() ? toExpressionRecursively(result, property.next()) : result; + } }