Skip to content

Support for sorting by subclass properties inside repository methods #3593

Closed as not planned
@agrancaric

Description

@agrancaric

Hello, when trying to sort by subclass property using Spring Data Jpa repository an exception is thrown, however when using standard JPA the query executes fine. The problem seems to be in PropertyPath that only looks at the parent properties and throws an exception if the property is not found. For now I've added a workaround to also look at the subclasses in our project (https://github.com/croz-ltd/nrich/blob/dbd018ed73bc49f0f0bfd53c59435defcf1fed49/nrich-search/src/main/java/org/springframework/data/jpa/repository/query/NrichQueryUtils.java#L63) but I would prefer not to have to override and copy parts of QueryUtils. Is there an option to add such support in spring-data-jpa? The example project and exception stacktrace are given bellow.

spring-data-jpa-sorting-error.zip

No property 'childProperty' found for type 'Parent'
org.springframework.data.mapping.PropertyReferenceException: No property 'childProperty' found for type 'Parent'
  at org.springframework.data.mapping.PropertyPath.<init>(PropertyPath.java:94)
  at org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:455)
  at org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:431)
  at org.springframework.data.mapping.PropertyPath.lambda$from$0(PropertyPath.java:384)
  at java.base/java.util.concurrent.ConcurrentMap.computeIfAbsent(ConcurrentMap.java:330)
  at org.springframework.data.mapping.PropertyPath.from(PropertyPath.java:366)
  at org.springframework.data.mapping.PropertyPath.from(PropertyPath.java:344)
  at org.springframework.data.jpa.repository.query.QueryUtils.toJpaOrder(QueryUtils.java:753)
  at org.springframework.data.jpa.repository.query.QueryUtils.toOrders(QueryUtils.java:706)
  at org.springframework.data.jpa.repository.support.SimpleJpaRepository.getQuery(SimpleJpaRepository.java:760)
  at org.springframework.data.jpa.repository.support.SimpleJpaRepository.getQuery(SimpleJpaRepository.java:741)
  at org.springframework.data.jpa.repository.support.SimpleJpaRepository.findAll(SimpleJpaRepository.java:419)
  at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
  at java.base/java.lang.reflect.Method.invoke(Method.java:580)
  at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:355)
  at org.springframework.data.repository.core.support.RepositoryMethodInvoker$RepositoryFragmentMethodInvoker.lambda$new$0(RepositoryMethodInvoker.java:277)
  at org.springframework.data.repository.core.support.RepositoryMethodInvoker.doInvoke(RepositoryMethodInvoker.java:170)
  at org.springframework.data.repository.core.support.RepositoryMethodInvoker.invoke(RepositoryMethodInvoker.java:158)
  at org.springframework.data.repository.core.support.RepositoryComposition$RepositoryFragments.invoke(RepositoryComposition.java:516)
  at org.springframework.data.repository.core.support.RepositoryComposition.invoke(RepositoryComposition.java:285)
  at org.springframework.data.repository.core.support.RepositoryFactorySupport$ImplementationMethodExecutionInterceptor.invoke(RepositoryFactorySupport.java:628)
  at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
  at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.doInvoke(QueryExecutorMethodInterceptor.java:173)
  at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.invoke(QueryExecutorMethodInterceptor.java:148)
  at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
  at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:70)
  at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
  at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:379)
  at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119)
  at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
  at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:138)
  at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
  at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:165)
  at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
  at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97)
  at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
  at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:223)
  at jdk.proxy3/jdk.proxy3.$Proxy108.findAll(Unknown Source)
  at net.example.SortingTest.shouldSortThroughRepository(SortingTest.java:62)
  at java.base/java.lang.reflect.Method.invoke(Method.java:580)
  at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
  at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)

Metadata

Metadata

Assignees

No one assigned

    Labels

    status: declinedA suggestion or change that we don't feel we should currently apply

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions