【发布时间】:2020-07-20 14:28:03
【问题描述】:
我有带有字符串字段的实体:
@Data
@Entity
@Table(name = "document")
public class Document {
...
private String docNumber;
...
}
我使用 JpaSpecificationExecutor#findAll 来查找行:
Page<T> findAll(@Nullable Specification<T> spec, Pageable pageable);
我需要按 docNumber 作为数值排序。
我尝试将其设置为 pageable#sort 值 new JpaSort("length(docNumber)")(就像从这里回答 - https://stackoverflow.com/a/46215275),但得到异常:
org.springframework.data.mapping.PropertyReferenceException: No property (length(docNumber)) found for type Payroll!
at org.springframework.data.mapping.PropertyPath.<init>(PropertyPath.java:94)
at org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:358)
at org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:334)
at org.springframework.data.mapping.PropertyPath.lambda$from$0(PropertyPath.java:287)
at java.util.concurrent.ConcurrentMap.computeIfAbsent(ConcurrentMap.java:324)
at org.springframework.data.mapping.PropertyPath.from(PropertyPath.java:269)
at org.springframework.data.mapping.PropertyPath.from(PropertyPath.java:252)
at org.springframework.data.jpa.repository.query.QueryUtils.toJpaOrder(QueryUtils.java:563)
at org.springframework.data.jpa.repository.query.QueryUtils.toOrders(QueryUtils.java:516)
at org.springframework.data.jpa.repository.support.SimpleJpaRepository.getQuery(SimpleJpaRepository.java:630)
at org.springframework.data.jpa.repository.support.SimpleJpaRepository.getQuery(SimpleJpaRepository.java:584)
at org.springframework.data.jpa.repository.support.SimpleJpaRepository.findAll(SimpleJpaRepository.java:387)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.data.repository.core.support.RepositoryComposition$RepositoryFragments.invoke(RepositoryComposition.java:377)
at org.springframework.data.repository.core.support.RepositoryComposition.invoke(RepositoryComposition.java:200)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$ImplementationMethodExecutionInterceptor.invoke(RepositoryFactorySupport.java:641)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:605)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:590)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:59)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:294)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:139)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:135)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
at org.springframework.data.repository.core.support.SurroundingTransactionDetectorMethodInterceptor.invoke(SurroundingTransactionDetectorMethodInterceptor.java:61)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)
at com.sun.proxy.$Proxy285.findAll(Unknown Source)
如何按 docNumber 作为数值排序?
PS:Specification<T> spec 具有非平凡逻辑的参数,我认为不能用 @Query 代替(就像这里的回答 - https://stackoverflow.com/a/46215275)
【问题讨论】:
-
length是一个 Java 函数,在 JPQL 中不存在(也不会将VARCHAR转换为传统意义上的NUMBER。在此处尝试建议的方法:@ 987654323@ -
是的,
length不会转换为number,但我们可以根据长度创建所需的排序。示例:select * from document order by length(doc_number), doc_number; -
有趣的方法。
标签: spring spring-boot spring-data-jpa