pramoth / specification-with-projection

Support projections with JpaSpecificationExecutor.findAll(Specification,Pageable) for Spring Data JPA
MIT License
164 stars 56 forks source link

Upgrade to 2.0.2 from 2.0.1 forces Id to exist on all entities #24

Open barryspearce opened 3 years ago

barryspearce commented 3 years ago

Upgrading from 2.0.1 to 2.0.2 caused significant breaking issues across my repositories such that the primary key type needed to be added to all declarations - which is unexpected from a point release.

However, now JpaSpecificationExecutorWithProjection refuses to operate on entities without an "id" property, whereas it did before.

I was using 2.0.1 to provide specification queries on the Spring Security persistent login for management purposes. However, the primary key of the Persistent Login is not called Id.

This knock-on effect of introducing findById() means that the usability of the class has been reduced. One attempted workaround I tried was to add a nullable "id" field to the entity - but this is the tail wagging the dog, and seems excessive when the previous version worked. However this attempt failed with the following exception:

Caused by: java.lang.NoSuchMethodError: 'java.util.Map org.springframework.data.jpa.repository.support.CrudMethodMetadata.getQueryHints()'
        at th.co.geniustree.springdata.jpa.repository.support.DefaultQueryHints.asMap(DefaultQueryHints.java:118)
        at th.co.geniustree.springdata.jpa.repository.support.DefaultQueryHints.iterator(DefaultQueryHints.java:103)
        at th.co.geniustree.springdata.jpa.repository.support.JpaSpecificationExecutorWithProjectionImpl.applyQueryHints(JpaSpecificationExecutorWithProjectionImpl.java:221)
        at th.co.geniustree.springdata.jpa.repository.support.JpaSpecificationExecutorWithProjectionImpl.applyRepositoryMethodMetadata(JpaSpecificationExecutorWithProjectionImpl.java:212)
        at th.co.geniustree.springdata.jpa.repository.support.JpaSpecificationExecutorWithProjectionImpl.getTupleQuery(JpaSpecificationExecutorWithProjectionImpl.java:179)
        at th.co.geniustree.springdata.jpa.repository.support.JpaSpecificationExecutorWithProjectionImpl.findAll(JpaSpecificationExecutorWithProjectionImpl.java:121)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:64)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:564)
        at org.springframework.data.repository.core.support.RepositoryMethodInvoker$RepositoryFragmentMethodInvoker.lambda$new$0(RepositoryMethodInvoker.java:289)
        at org.springframework.data.repository.core.support.RepositoryMethodInvoker.doInvoke(RepositoryMethodInvoker.java:137)
        at org.springframework.data.repository.core.support.RepositoryMethodInvoker.invoke(RepositoryMethodInvoker.java:121)
        at org.springframework.data.repository.core.support.RepositoryComposition$RepositoryFragments.invoke(RepositoryComposition.java:529)
        at org.springframework.data.repository.core.support.RepositoryComposition.invoke(RepositoryComposition.java:285)
        at org.springframework.data.repository.core.support.RepositoryFactorySupport$ImplementationMethodExecutionInterceptor.invoke(RepositoryFactorySupport.java:599)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
        at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.doInvoke(QueryExecutorMethodInterceptor.java:163)
        at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.invoke(QueryExecutorMethodInterceptor.java:138)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
        at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:123)
        at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:388)
        at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
        at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:137)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
        at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:174)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
        at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
        at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:215)
        at com.sun.proxy.$Proxy170.findAll(Unknown Source)