DATAJPA-564 - Allow SpEL expressions to be the only consumer of query method parameters.
We now allow the parameters of query methods to also be exclusively consumed by expressions within a given query string. Previously this wasn't possible due to to strict checks for parameter usage in JpaQueryMethod. Relax check for query param usage in JpaQueryMethod. Enabled HSQLDB support for oracle syntax to be able to use the ROWNUM() function for pagination.
This commit is contained in:
committed by
Oliver Gierke
parent
55f1131b2f
commit
0602084c0e
@@ -46,8 +46,10 @@ final class NativeJpaQuery extends AbstractStringBasedJpaQuery {
|
||||
|
||||
Parameters<?, ?> parameters = method.getParameters();
|
||||
boolean hasPagingOrSortingParameter = parameters.hasPageableParameter() || parameters.hasSortParameter();
|
||||
boolean containsPageableOrSortInQueryExpression = queryString.contains("#pageable")
|
||||
|| queryString.contains("#sort");
|
||||
|
||||
if (hasPagingOrSortingParameter) {
|
||||
if (hasPagingOrSortingParameter && !containsPageableOrSortInQueryExpression) {
|
||||
throw new InvalidJpaQueryMethodException(
|
||||
"Cannot use native queries with dynamic sorting and/or pagination in method " + method);
|
||||
}
|
||||
|
||||
@@ -63,6 +63,10 @@ class SpelExpressionStringQueryParameterBinder extends StringQueryParameterBinde
|
||||
*/
|
||||
private <T extends Query> T potentiallyBindExpressionParameters(T jpaQuery) {
|
||||
|
||||
if (jpaQuery.getParameters().isEmpty()) {
|
||||
return jpaQuery;
|
||||
}
|
||||
|
||||
for (ParameterBinding binding : query.getParameterBindings()) {
|
||||
|
||||
if (binding.isExpression()) {
|
||||
|
||||
@@ -74,4 +74,10 @@ public class EclipseLinkNamespaceUserRepositoryTests extends NamespaceUserReposi
|
||||
*/
|
||||
@Override
|
||||
public void findByElementCollectionAttribute() {}
|
||||
|
||||
/**
|
||||
* Temporarily ignored until issue with native queries and pagination is resolved.
|
||||
*/
|
||||
@Override
|
||||
public void shouldFindUsersInNativeQueryWithPagination() {}
|
||||
}
|
||||
|
||||
@@ -87,4 +87,10 @@ public class OpenJpaNamespaceUserRepositoryTests extends NamespaceUserRepository
|
||||
List<User> resultList = query.getResultList();
|
||||
assertThat(resultList.size(), is(2));
|
||||
}
|
||||
|
||||
/**
|
||||
* Temporarily ignored until issue with native queries and pagination is resolved.
|
||||
*/
|
||||
@Override
|
||||
public void shouldFindUsersInNativeQueryWithPagination() {}
|
||||
}
|
||||
|
||||
@@ -1732,6 +1732,27 @@ public class UserRepositoryTests {
|
||||
assertThat(users.get(0), is(secondUser));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAJPA-564
|
||||
*/
|
||||
@Test
|
||||
public void shouldFindUsersInNativeQueryWithPagination() {
|
||||
|
||||
flushTestUsers();
|
||||
|
||||
Page<User> users = repository.findUsersInNativeQueryWithPagination(new PageRequest(0, 2));
|
||||
|
||||
assertThat(users.getContent(), hasSize(2));
|
||||
assertThat(users.getContent().get(0), is(firstUser));
|
||||
assertThat(users.getContent().get(1), is(secondUser));
|
||||
|
||||
users = repository.findUsersInNativeQueryWithPagination(new PageRequest(1, 2));
|
||||
|
||||
assertThat(users.getContent(), hasSize(2));
|
||||
assertThat(users.getContent().get(0), is(thirdUser));
|
||||
assertThat(users.getContent().get(1), is(fourthUser));
|
||||
}
|
||||
|
||||
private Page<User> executeSpecWithSort(Sort sort) {
|
||||
|
||||
flushTestUsers();
|
||||
|
||||
@@ -519,4 +519,12 @@ public interface UserRepository extends JpaRepository<User, Integer>, JpaSpecifi
|
||||
*/
|
||||
@Query("select u from User u where u.firstname = ?#{[0]}")
|
||||
List<User> findUsersByFirstnameForSpELExpressionWithParameterIndexOnly(String firstname);
|
||||
|
||||
/**
|
||||
* @see DATAJPA-564
|
||||
*/
|
||||
@Query(
|
||||
value = "select * from (select rownum() as RN, u.* from User u) where RN between ?#{ #pageable.offset -1} and ?#{#pageable.offset + #pageable.pageSize}",
|
||||
countQuery = "select count(u.id) from User u", nativeQuery = true)
|
||||
Page<User> findUsersInNativeQueryWithPagination(Pageable pageable);
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
<bean name="sampleEvaluationContextExtension" class="org.springframework.data.jpa.repository.sample.SampleEvaluationContextExtension"/>
|
||||
|
||||
<jdbc:embedded-database id="dataSource" type="HSQL">
|
||||
<jdbc:script execution="INIT" separator="/;" location="classpath:scripts/hsqldb-init.sql"/>
|
||||
<jdbc:script execution="INIT" separator="/;" location="classpath:scripts/schema-stored-procedures.sql"/>
|
||||
</jdbc:embedded-database>
|
||||
|
||||
|
||||
3
src/test/resources/scripts/hsqldb-init.sql
Normal file
3
src/test/resources/scripts/hsqldb-init.sql
Normal file
@@ -0,0 +1,3 @@
|
||||
/;
|
||||
SET DATABASE SQL SYNTAX ORA TRUE
|
||||
/;
|
||||
Reference in New Issue
Block a user