添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

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 Custom finders with PageRequest (instead of Pageable) method parameter causes IllegalArgumentException #2013 Custom finders with PageRequest (instead of Pageable) method parameter causes IllegalArgumentException #2013 spring-projects-issues opened this issue Apr 30, 2020 · 6 comments

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 {
	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

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.

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);
          

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.

… 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.
… 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.
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.
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.
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.
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.
…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.
changed the title findBy<property>In(int[], PageRequest) causes IllegalArgumentException [DATAJPA-1718] Custom finders with PageRequest method parameter causes IllegalArgumentException May 12, 2022 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
…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.
…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.
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.
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.
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.