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 a6e902a78..8d41f865c 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 @@ -77,6 +77,7 @@ import org.springframework.util.StringUtils; * @author Diego Krupitza * @author Jędrzej Biedrzycki * @author Darin Manica + * @author Simon Paradies */ public abstract class QueryUtils { @@ -182,7 +183,7 @@ public abstract class QueryUtils { builder = new StringBuilder(); // any function call including parameters within the brackets - builder.append("\\w+\\s*\\([\\w\\.,\\s'=]+\\)"); + builder.append("\\w+\\s*\\([\\w\\.,\\s'=:\\\\?]+\\)"); // the potential alias builder.append("\\s+[as|AS]+\\s+(([\\w\\.]+))"); 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 7b0bff041..c44584efb 100644 --- a/src/test/java/org/springframework/data/jpa/repository/UserRepositoryTests.java +++ b/src/test/java/org/springframework/data/jpa/repository/UserRepositoryTests.java @@ -96,6 +96,8 @@ import org.springframework.transaction.annotation.Transactional; * @author Jesse Wouters * @author Greg Turnquist * @author Diego Krupitza + * @author Daniel Shuy + * @author Simon Paradies */ @ExtendWith(SpringExtension.class) @ContextConfiguration("classpath:application-context.xml") @@ -2676,6 +2678,16 @@ public class UserRepositoryTests { assertThat(repository.exists(hundredYearsOld)).isTrue(); } + @Test // GH-2045, GH-425 + public void correctlyBuildSortClauseWhenSortingByFunctionAliasAndFunctionContainsPositionalParameters() { + repository.findAllAndSortByFunctionResultPositionalParameter("prefix", "suffix", Sort.by("idWithPrefixAndSuffix")); + } + + @Test // GH-2045, GH-425 + public void correctlyBuildSortClauseWhenSortingByFunctionAliasAndFunctionContainsNamedParameters() { + repository.findAllAndSortByFunctionResultNamedParameter("prefix", "suffix", Sort.by("idWithPrefixAndSuffix")); + } + 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 e176cca13..32ca93f16 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 @@ -54,6 +54,7 @@ import org.springframework.transaction.annotation.Transactional; * @author Andrey Kovalev * @author JyotirmoyVS * @author Greg Turnquist + * @author Simon Paradies */ public interface UserRepository extends JpaRepository, JpaSpecificationExecutor, UserRepositoryCustom { @@ -625,6 +626,17 @@ public interface UserRepository // GH-2408 List findAllInterfaceProjectedBy(); + // GH-2045, GH-425 + @Query("select concat(?1,u.id,?2) as idWithPrefixAndSuffix from #{#entityName} u") + List findAllAndSortByFunctionResultPositionalParameter( + @Param("positionalParameter1") String positionalParameter1, + @Param("positionalParameter2") String positionalParameter2, Sort sort); + + // GH-2045, GH-425 + @Query("select concat(:namedParameter1,u.id,:namedParameter2) as idWithPrefixAndSuffix from #{#entityName} u") + List findAllAndSortByFunctionResultNamedParameter(@Param("namedParameter1") String namedParameter1, + @Param("namedParameter2") String namedParameter2, Sort sort); + interface RolesAndFirstname { String getFirstname();