Search code examples
javaspring-bootspring-data-jpajpqlspring-el

SpEL are not read in @Query after Spring Boot 2.0.0 M7 update


I had my Spring Boot 2.0.0 M3 application developed. Everything worked just fine. But after updating to Spring Boot 2.0.0 M7 (or even to Spring Boot 2.0.0 M5 more recently) SpELs in my @Query are not longer compiled properly. For example

@Query("SELECT m FROM com.mypackage.models.Model m WHERE m.status IN 
(:#{T(com.mypackage.utils.Constants).SPECIAL_STATUSES})")
public List<Model> findModelWithSpecialStatuses();

And I get the following exception

org.springframework.dao.InvalidDataAccessApiUsageException: Unknown parameter name : __$synthetic$__1; nested exception is java.lang.IllegalArgumentException: Unknown parameter name : __$synthetic$__1
Caused by: java.lang.IllegalArgumentException: Unknown parameter name : __$synthetic$__1
at org.hibernate.query.internal.QueryParameterBindingsImpl.getBinding(QueryParameterBindingsImpl.java:208) ~[hibernate-core-5.2.12.Final.jar:5.2.12.Final]
at org.hibernate.query.internal.AbstractProducedQuery.setParameter(AbstractProducedQuery.java:486) ~[hibernate-core-5.2.12.Final.jar:5.2.12.Final]
at org.hibernate.query.internal.AbstractProducedQuery.setParameter(AbstractProducedQuery.java:104) ~[hibernate-core-5.2.12.Final.jar:5.2.12.Final]
at org.springframework.data.jpa.repository.query.QueryParameterSetter$NamedOrIndexedQueryParameterSetter.setParameter(QueryParameterSetter.java:99) ~[spring-data-jpa-2.0.2.RELEASE.jar:2.0.2.RELEASE]
at org.springframework.data.jpa.repository.query.ParameterBinder.lambda$bind$0(ParameterBinder.java:57) ~[spring-data-jpa-2.0.2.RELEASE.jar:2.0.2.RELEASE]
at java.util.ArrayList.forEach(ArrayList.java:1249) ~[na:1.8.0_131]
at java.util.Collections$UnmodifiableCollection.forEach(Collections.java:1080) ~[na:1.8.0_131]
at org.springframework.data.jpa.repository.query.ParameterBinder.bind(ParameterBinder.java:57) ~[spring-data-jpa-2.0.2.RELEASE.jar:2.0.2.RELEASE]
at org.springframework.data.jpa.repository.query.AbstractStringBasedJpaQuery.doCreateCountQuery(AbstractStringBasedJpaQuery.java:108) ~[spring-data-jpa-2.0.2.RELEASE.jar:2.0.2.RELEASE]
at org.springframework.data.jpa.repository.query.AbstractJpaQuery.createCountQuery(AbstractJpaQuery.java:228) ~[spring-data-jpa-2.0.2.RELEASE.jar:2.0.2.RELEASE]
at org.springframework.data.jpa.repository.query.JpaQueryExecution$PagedExecution.count(JpaQueryExecution.java:199) ~[spring-data-jpa-2.0.2.RELEASE.jar:2.0.2.RELEASE]
at org.springframework.data.jpa.repository.query.JpaQueryExecution$PagedExecution.lambda$doExecute$0(JpaQueryExecution.java:193) ~[spring-data-jpa-2.0.2.RELEASE.jar:2.0.2.RELEASE]
at org.springframework.data.repository.support.PageableExecutionUtils.getPage(PageableExecutionUtils.java:62) ~[spring-data-commons-2.0.2.RELEASE.jar:2.0.2.RELEASE]
at org.springframework.data.jpa.repository.query.JpaQueryExecution$PagedExecution.doExecute(JpaQueryExecution.java:192) ~[spring-data-jpa-2.0.2.RELEASE.jar:2.0.2.RELEASE]
at org.springframework.data.jpa.repository.query.JpaQueryExecution.execute(JpaQueryExecution.java:89) ~[spring-data-jpa-2.0.2.RELEASE.jar:2.0.2.RELEASE]
at org.springframework.data.jpa.repository.query.AbstractJpaQuery.doExecute(AbstractJpaQuery.java:127) ~[spring-data-jpa-2.0.2.RELEASE.jar:2.0.2.RELEASE]
at org.springframework.data.jpa.repository.query.AbstractJpaQuery.execute(AbstractJpaQuery.java:116) ~[spring-data-jpa-2.0.2.RELEASE.jar:2.0.2.RELEASE]
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:597) ~[spring-data-commons-2.0.2.RELEASE.jar:2.0.2.RELEASE]
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:580) ~[spring-data-commons-2.0.2.RELEASE.jar:2.0.2.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185) ~[spring-aop-5.0.2.RELEASE.jar:5.0.2.RELEASE]
at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:59) ~[spring-data-commons-2.0.2.RELEASE.jar:2.0.2.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185) ~[spring-aop-5.0.2.RELEASE.jar:5.0.2.RELEASE]
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:294) ~[spring-tx-5.0.2.RELEASE.jar:5.0.2.RELEASE]
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98) ~[spring-tx-5.0.2.RELEASE.jar:5.0.2.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185) ~[spring-aop-5.0.2.RELEASE.jar:5.0.2.RELEASE]
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:139) ~[spring-tx-5.0.2.RELEASE.jar:5.0.2.RELEASE]
... 115 common frames omitted

(:#{T(com.mypackage.utils.Constants).SPECIAL_STATUSES}) - is a List of Objects


Solution

  • It turned out, that Hibernate in newer versions of Spring Boot optimizes its queries, so some of parameters are not visible anymore. The fastest solution I found was simply checking those parameters for not null in my @Query