0

实体:

    @MappedSuperclass
    @Data
    public abstract class Account {
        @Id
        @GeneratedValue(strategy = GenerationType.SEQUENCE)
        private Integer id;
        ...
        private boolean status;
        ...
    }
    @Entity
    public class AndroidAccount extends Account {
        private String packageApk;
        private String password;
    }

规范生成器:

    public Builder addFilter(String fieldName, FilterOperation operation, String value) {
                ...
                    } else if (fieldName.equals("status")) {
                        boolean isBanned = Boolean.parseBoolean(value);
                        specification = isBanned ? specification.and(isBanned()) : specification.and(isNotBanned());
                    }
                    ...
                return this;
            }    
            protected Specification<T> isBanned() {
                return (root, query, builder) ->  builder.isFalse(root.get("status"));
            }
        
            protected Specification<T> isNotBanned() {
                return (root, query, builder) ->  builder.isTrue(root.get("status"));
            }

存储库:


    @Repository
    public interface AndroidRepository extends PagingAndSortingRepository<AndroidAccount, Integer>,
                                                JpaSpecificationExecutor<AndroidAccount> {
    }
Invoke here:

    Specification<AndroidAccount> specification = new AndroidSpecs().builder()
                    .addFilter("domain", FilterOperation.EQUALS, "Test domain1")
                    .addFilter("status", FilterOperation.EQUALS, "false")
                    .build();
    
            List<AndroidAccount> accountList = androidRepository.findAll(specification);
            accountList.forEach(System.out::println);

使用任何字符串字段都可以正常工作,但使用布尔值抛出:

    org.springframework.dao.InvalidDataAccessApiUsageException: Parameter value [false] did not match expected type [java.lang.Boolean (n/a)]; nested exception is java.lang.IllegalArgumentException: Parameter value [false] did not match expected type [java.lang.Boolean (n/a)]
    
        at org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:374)
        at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:257)
        at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:528)
        at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:61)
        at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:242)
        at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:153)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
        at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:178)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
        at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:95)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
        at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)
        at com.sun.proxy.$Proxy93.findAll(Unknown Source)
        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.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344)
        at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:205)
        at com.sun.proxy.$Proxy96.findAll(Unknown Source)
    ...
Caused by: java.lang.IllegalArgumentException: Parameter value [false] did not match expected type [java.lang.Boolean (n/a)]
    at org.hibernate.query.spi.QueryParameterBindingValidator.validate(QueryParameterBindingValidator.java:54)
    at org.hibernate.query.spi.QueryParameterBindingValidator.validate(QueryParameterBindingValidator.java:27)
    at org.hibernate.query.internal.QueryParameterBindingImpl.validate(QueryParameterBindingImpl.java:90)
    at org.hibernate.query.internal.QueryParameterBindingImpl.setBindValue(QueryParameterBindingImpl.java:55)
    at org.hibernate.query.internal.AbstractProducedQuery.setParameter(AbstractProducedQuery.java:490)
    at org.hibernate.query.internal.AbstractProducedQuery.setParameter(AbstractProducedQuery.java:111)
    at org.hibernate.query.criteria.internal.compile.CriteriaCompiler$1$1.bind(CriteriaCompiler.java:135)
    at org.hibernate.query.criteria.internal.CriteriaQueryImpl$1.buildCompiledQuery(CriteriaQueryImpl.java:364)
    at org.hibernate.query.criteria.internal.compile.CriteriaCompiler.compile(CriteriaCompiler.java:165)
    at org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:742)
    at org.hibernate.internal.AbstractSessionImpl.createQuery(AbstractSessionImpl.java:23)
    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.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:314)
    at com.sun.proxy.$Proxy86.createQuery(Unknown Source)
    at org.springframework.data.jpa.repository.support.SimpleJpaRepository.getQuery(SimpleJpaRepository.java:700)
    at org.springframework.data.jpa.repository.support.SimpleJpaRepository.getQuery(SimpleJpaRepository.java:677)
    at org.springframework.data.jpa.repository.support.SimpleJpaRepository.findAll(SimpleJpaRepository.java:433)
    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.ImplementationInvocationMetadata.invoke(ImplementationInvocationMetadata.java:72)
    at org.springframework.data.repository.core.support.RepositoryComposition$RepositoryFragments.invoke(RepositoryComposition.java:382)
    at org.springframework.data.repository.core.support.RepositoryComposition.invoke(RepositoryComposition.java:205)
4

1 回答 1

1
Specification<AndroidAccount> specification = new AndroidSpecs().builder()
                .addFilter("domain", FilterOperation.EQUALS, "Test domain1")
                .addFilter("status", FilterOperation.EQUALS, Boolean.FALSE)
                .build();

不要将“false”作为 String 传递,而是尝试传递 Boolean.FALSE。由于错误表明传递的参数不符合预期的布尔类型。

如果没有特定用例,请尝试从 boolean(primitive) --> Boolean(Wrapper Class) 更改实体中的“状态”字段。

于 2020-08-15T08:48:43.223 回答