Skip to content

Custom finders with PageRequest (instead of Pageable) method parameter causes IllegalArgumentException #2013

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
spring-projects-issues opened this issue Apr 30, 2020 · 6 comments
Assignees
Labels
status: superseded An issue that has been superseded by another type: task A general task

Comments

@spring-projects-issues
Copy link

Mark Paluch opened DATAJPA-1718 and commented

A query using the In keyword accepting an array/collection and a PageRequest causes: IllegalArgumentException: At least 2 parameter(s) provided but only 1 parameter(s) present in query.

 

Repository declaration:

 

interface MyEntityRepository extends JpaRepository<MyEntity, Long> {
	Page<MyEntity> findByStatusIn(List<Integer> status, PageRequest pageRequest);
}

@Entity
@Data
class MyEntity {

	@Id
	Long myId;
	int status;
}

Stack trace:

Caused by: org.springframework.dao.InvalidDataAccessApiUsageException: At least 2 parameter(s) provided but only 1 parameter(s) present in query.; nested exception is java.lang.IllegalArgumentException: At least 2 parameter(s) provided but only 1 parameter(s) present in query.
	at org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:374) ~[spring-orm-5.2.5.RELEASE.jar:5.2.5.RELEASE]
	at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:257) ~[spring-orm-5.2.5.RELEASE.jar:5.2.5.RELEASE]
	at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:528) ~[spring-orm-5.2.5.RELEASE.jar:5.2.5.RELEASE]
	at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:61) ~[spring-tx-5.2.5.RELEASE.jar:5.2.5.RELEASE]
	at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:242) ~[spring-tx-5.2.5.RELEASE.jar:5.2.5.RELEASE]
	at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:153) ~[spring-tx-5.2.5.RELEASE.jar:5.2.5.RELEASE]
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.2.5.RELEASE.jar:5.2.5.RELEASE]
	at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:149) ~[spring-data-jpa-2.2.6.RELEASE.jar:2.2.6.RELEASE]
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.2.5.RELEASE.jar:5.2.5.RELEASE]
	at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:95) ~[spring-aop-5.2.5.RELEASE.jar:5.2.5.RELEASE]
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.2.5.RELEASE.jar:5.2.5.RELEASE]
	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212) ~[spring-aop-5.2.5.RELEASE.jar:5.2.5.RELEASE]
	at com.sun.proxy.$Proxy65.findByStatusIn(Unknown Source) ~[na:na]
	at com.example.demo.DemoApplication.lambda$clr$0(DemoApplication.java:36) [classes/:na]
	at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:784) [spring-boot-2.2.6.RELEASE.jar:2.2.6.RELEASE]
	... 5 common frames omitted
Caused by: java.lang.IllegalArgumentException: At least 2 parameter(s) provided but only 1 parameter(s) present in query.
	at org.springframework.util.Assert.isTrue(Assert.java:136) ~[spring-core-5.2.5.RELEASE.jar:5.2.5.RELEASE]
	at org.springframework.data.jpa.repository.query.QueryParameterSetterFactory$CriteriaQueryParameterSetterFactory.create(QueryParameterSetterFactory.java:297) ~[spring-data-jpa-2.2.6.RELEASE.jar:2.2.6.RELEASE]
	at org.springframework.data.jpa.repository.query.ParameterBinderFactory.createQueryParameterSetter(ParameterBinderFactory.java:140) ~[spring-data-jpa-2.2.6.RELEASE.jar:2.2.6.RELEASE]
	at org.springframework.data.jpa.repository.query.ParameterBinderFactory.createSetters(ParameterBinderFactory.java:129) ~[spring-data-jpa-2.2.6.RELEASE.jar:2.2.6.RELEASE]
	at org.springframework.data.jpa.repository.query.ParameterBinderFactory.createSetters(ParameterBinderFactory.java:121) ~[spring-data-jpa-2.2.6.RELEASE.jar:2.2.6.RELEASE]
	at org.springframework.data.jpa.repository.query.ParameterBinderFactory.createCriteriaBinder(ParameterBinderFactory.java:72) ~[spring-data-jpa-2.2.6.RELEASE.jar:2.2.6.RELEASE]
	at org.springframework.data.jpa.repository.query.PartTreeJpaQuery$QueryPreparer.getBinder(PartTreeJpaQuery.java:328) ~[spring-data-jpa-2.2.6.RELEASE.jar:2.2.6.RELEASE]
	at org.springframework.data.jpa.repository.query.PartTreeJpaQuery$QueryPreparer.createQuery(PartTreeJpaQuery.java:234) ~[spring-data-jpa-2.2.6.RELEASE.jar:2.2.6.RELEASE]
	at org.springframework.data.jpa.repository.query.PartTreeJpaQuery.doCreateQuery(PartTreeJpaQuery.java:106) ~[spring-data-jpa-2.2.6.RELEASE.jar:2.2.6.RELEASE]
	at org.springframework.data.jpa.repository.query.AbstractJpaQuery.createQuery(AbstractJpaQuery.java:226) ~[spring-data-jpa-2.2.6.RELEASE.jar:2.2.6.RELEASE]
	at org.springframework.data.jpa.repository.query.JpaQueryExecution$PagedExecution.doExecute(JpaQueryExecution.java:175) ~[spring-data-jpa-2.2.6.RELEASE.jar:2.2.6.RELEASE]
	at org.springframework.data.jpa.repository.query.JpaQueryExecution.execute(JpaQueryExecution.java:88) ~[spring-data-jpa-2.2.6.RELEASE.jar:2.2.6.RELEASE]
	at org.springframework.data.jpa.repository.query.AbstractJpaQuery.doExecute(AbstractJpaQuery.java:154) ~[spring-data-jpa-2.2.6.RELEASE.jar:2.2.6.RELEASE]
	at org.springframework.data.jpa.repository.query.AbstractJpaQuery.execute(AbstractJpaQuery.java:142) ~[spring-data-jpa-2.2.6.RELEASE.jar:2.2.6.RELEASE]
	at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:618) ~[spring-data-commons-2.2.6.RELEASE.jar:2.2.6.RELEASE]
	at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:605) ~[spring-data-commons-2.2.6.RELEASE.jar:2.2.6.RELEASE]
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.2.5.RELEASE.jar:5.2.5.RELEASE]
	at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:80) ~[spring-data-commons-2.2.6.RELEASE.jar:2.2.6.RELEASE]
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.2.5.RELEASE.jar:5.2.5.RELEASE]
	at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:366) ~[spring-tx-5.2.5.RELEASE.jar:5.2.5.RELEASE]
	at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:118) ~[spring-tx-5.2.5.RELEASE.jar:5.2.5.RELEASE]
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.2.5.RELEASE.jar:5.2.5.RELEASE]
	at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:139) ~[spring-tx-5.2.5.RELEASE.jar:5.2.5.RELEASE]
	... 14 common frames omitted

 


Reference URL: https://gitter.im/spring-projects/spring-data?at=5eaab03a7975db7ebfd654a8

@gregturn
Copy link
Contributor

Further details says that this...

Page<MyResult> findByStatusIn(Collection<Integer> status, PageRequest pageRequest);

...fails. But this...

Page<MyResult> findByStatusIn(Collection<Integer> status, Pageable pageRequest);

...works.

Should lead to a suitable test case.

@gregturn
Copy link
Contributor

Confirmed. The first test case below works, the second one fails.

	@Test // GH-2013
	void findByCollectionWithPageable() {

		flushTestUsers();

		Page<User> userPage = repository.findByAgeIn(List.of(28, 35), (Pageable) PageRequest.of(0, 2));

		assertThat(userPage).hasSize(2);
		assertThat(userPage.getTotalElements()).isEqualTo(2);
		assertThat(userPage.getTotalPages()).isEqualTo(1);
		assertThat(userPage.getContent()).containsExactlyInAnyOrder(firstUser, secondUser);
	}

	@Test
	void findByCollectionWithPageRequest() {

		flushTestUsers();

		Page<User> userPage = repository.findByAgeIn(List.of(28, 35), (PageRequest) PageRequest.of(0, 2));

		assertThat(userPage).hasSize(2);
		assertThat(userPage.getTotalElements()).isEqualTo(2);
		assertThat(userPage.getTotalPages()).isEqualTo(1);
		assertThat(userPage.getContent()).containsExactlyInAnyOrder(firstUser, secondUser);
	}

@gregturn
Copy link
Contributor

The problem is based on Spring Data Commons, where Pageable is on a special list, while PageRequest is not.

https://github.com/spring-projects/spring-data-commons/blob/main/src/main/java/org/springframework/data/repository/query/Parameter.java#L60

We need to possibly update the check for these parameters to do an .IsInstance() check.

@gregturn
Copy link
Contributor

gregturn added a commit to spring-projects/spring-data-commons that referenced this issue May 11, 2022
… type that extend those types.

A custom finder with PageRequest, even though it extends Pageable, will fail when it would work fine with a narrowed input.

Related: spring-projects/spring-data-jpa#2013

See #2626.
gregturn added a commit to spring-projects/spring-data-commons that referenced this issue May 11, 2022
… type that extend those types.

A custom finder with PageRequest, even though it extends Pageable, will fail when it would work fine with a narrowed input.

Related: spring-projects/spring-data-jpa#2013

See #2626.
gregturn added a commit to spring-projects/spring-data-commons that referenced this issue May 11, 2022
Spring Data Commons has a hard-coded list of special types than can be included in query methods including Pageable and Sort.

A custom finder with PageRequest, even though it extends Pageable, will fail when it would work fine with a narrowed input. This extends the list using an isAssignableFrom check.

Related: spring-projects/spring-data-jpa#2013

See #2626.
odrotbohm pushed a commit to spring-projects/spring-data-commons that referenced this issue May 12, 2022
Spring Data Commons has a hard-coded list of special types than can be included in query methods including Pageable and Sort.

A custom finder with PageRequest, even though it extends Pageable, will fail when it would work fine with a narrowed input. This extends the list using an assignability check.

Related: spring-projects/spring-data-jpa#2013
See #2626.
odrotbohm pushed a commit to spring-projects/spring-data-commons that referenced this issue May 12, 2022
Spring Data Commons has a hard-coded list of special types than can be included in query methods including Pageable and Sort.

A custom finder with PageRequest, even though it extends Pageable, will fail when it would work fine with a narrowed input. This extends the list using an assignability check.

Related: spring-projects/spring-data-jpa#2013
See #2626.
odrotbohm pushed a commit to spring-projects/spring-data-commons that referenced this issue May 12, 2022
Spring Data Commons has a hard-coded list of special types than can be included in query methods including Pageable and Sort.

A custom finder with PageRequest, even though it extends Pageable, will fail when it would work fine with a narrowed input. This extends the list using an assignability check.

Related: spring-projects/spring-data-jpa#2013
See #2626.
@odrotbohm
Copy link
Member

This should be fixed by spring-projects/spring-data-commons#2626.

@gregturn
Copy link
Contributor

Thanks @odrotbohm. I'm going to add a couple test cases using this issue to ensure things are working.

@gregturn gregturn reopened this May 12, 2022
@gregturn gregturn self-assigned this May 12, 2022
@gregturn gregturn added status: superseded An issue that has been superseded by another type: task A general task and removed type: bug A general bug labels May 12, 2022
gregturn added a commit that referenced this issue May 12, 2022
…arameter.

Spring Data Commons patched handling subclasses of special parameter types through spring-projects/spring-data-commons#2626. This commit adds test cases ensuring things work properly with Spring Data JPA.

See #2013.
@gregturn gregturn added this to the 3.0 M4 (2022.0.0) milestone May 12, 2022
@gregturn gregturn changed the title findBy<property>In(int[], PageRequest) causes IllegalArgumentException [DATAJPA-1718] Custom finders with PageRequest method parameter causes IllegalArgumentException May 12, 2022
@gregturn gregturn changed the title Custom finders with PageRequest method parameter causes IllegalArgumentException Custom finders with PageRequest (instead of Pageable) method parameter causes IllegalArgumentException May 12, 2022
gregturn added a commit that referenced this issue May 12, 2022
…arameter.

Spring Data Commons patched handling subclasses of special parameter types through spring-projects/spring-data-commons#2626. This commit adds test cases ensuring things work properly with Spring Data JPA.

See #2013.
gregturn added a commit that referenced this issue May 12, 2022
…arameter.

Spring Data Commons patched handling subclasses of special parameter types through spring-projects/spring-data-commons#2626. This commit adds test cases ensuring things work properly with Spring Data JPA.

See #2013.
gregturn added a commit that referenced this issue May 12, 2022
Spring Data Commons patched handling subclasses of special parameter types through spring-projects/spring-data-commons#2626. This commit adds test cases ensuring things work properly with Spring Data JPA.

See #2013.
gregturn added a commit that referenced this issue May 12, 2022
Spring Data Commons patched handling subclasses of special parameter types through spring-projects/spring-data-commons#2626. This commit adds test cases ensuring things work properly with Spring Data JPA.

See #2013.
gregturn added a commit that referenced this issue May 12, 2022
Spring Data Commons patched handling subclasses of special parameter types through spring-projects/spring-data-commons#2626. This commit adds test cases ensuring things work properly with Spring Data JPA.

See #2013.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: superseded An issue that has been superseded by another type: task A general task
Projects
None yet
Development

No branches or pull requests

4 participants