@QuerydslPredicate抛出异常

时间:2018-06-17 17:08:29

标签: java spring spring-boot spring-data-jpa querydsl

我正在尝试了解如何使用@QuerydslPredicate,但我的测试API在调用时失败:

Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.IllegalStateException: No primary or default constructor found for interface com.querydsl.core.types.Predicate] with root cause

java.lang.NoSuchMethodException: com.querydsl.core.types.Predicate.< init >()

这是我的Controller类中的方法:

@ResponseBody
@RequestMapping(value = "/user/query", method = RequestMethod.GET)
public Iterable<User> getByCriteria(@QuerydslPredicate(root = User.class) Predicate predicate)
{
    return this.userDao.getByCriteria(predicate);
}

我使用this春季博客文章和this example来尝试实施我的API,但我不明白我做错了什么。

编辑#1

pom.xml:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.example</groupId>
    <artifactId>email-encrypt</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <packaging>jar</packaging>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.2.RELEASE</version>
    </parent>
    <name>email-encrypt</name>
    <url>http://maven.apache.org</url>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <querydsl.version>4.1.4</querydsl.version>
        <springfox.version>2.6.1</springfox.version>
    </properties>

    <dependencies>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-mail</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>

        <dependency>
            <groupId>org.bouncycastle</groupId>
            <artifactId>bcprov-jdk15on</artifactId>
            <version>1.59</version>
        </dependency>

        <dependency>
            <groupId>org.bouncycastle</groupId>
            <artifactId>bcpkix-jdk15on</artifactId>
            <version>1.59</version>
        </dependency>

        <dependency>
            <groupId>org.bouncycastle</groupId>
            <artifactId>bcmail-jdk15on</artifactId>
            <version>1.59</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

        <dependency>
            <groupId>com.querydsl</groupId>
            <artifactId>querydsl-apt</artifactId>
            <version>${querydsl.version}</version>
        </dependency>

        <dependency>
            <groupId>com.querydsl</groupId>
            <artifactId>querydsl-jpa</artifactId>
            <version>${querydsl.version}</version>
        </dependency>

        <dependency>
            <groupId>org.apache.derby</groupId>
            <artifactId>derby</artifactId>
            <version>10.14.1.0</version>
            <scope>runtime</scope>
        </dependency>


        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>${springfox.version}</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>${springfox.version}</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.16.20</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.16.20</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>com.mysema.maven</groupId>
                <artifactId>apt-maven-plugin</artifactId>
                <version>1.1.3</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>process</goal>
                        </goals>
                        <configuration>
                            <outputDirectory>${build.directory}/generated-sources/java</outputDirectory>
                            <processor>com.querydsl.apt.jpa.JPAAnnotationProcessor</processor>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

编辑#2

我已经创建了一个示例项目here

4 个答案:

答案 0 :(得分:0)

我认为您的问题在于您的pom.xml。请确保您使用的是query-dsl的兼容版本。例如,如果您使用spring-data-jpa 2.0.8,则应使用querydsl-* 4.1.4 +

<dependency>
    <groupId>org.springframework.data</groupId>
    <artifactId>spring-data-jpa</artifactId>
    <version>2.0.8.RELEASE</version>
</dependency>

<dependency>
    <groupId>com.querydsl</groupId>
    <artifactId>querydsl-*</artifactId>
    <version>4.1.4</version>
</dependency>

您可以在maven repository签入您需要的版本

编辑1 尝试将querydsl-core添加到您的maven:

 <dependency>
        <groupId>com.querydsl</groupId>
        <artifactId>querydsl-core</artifactId>
        <version>4.1.4</version>
 </dependency>

答案 1 :(得分:0)

如果您在swagger配置类上将@Configuration注释掉,它将起作用。我仍在尝试理解为什么,我猜想带有该注解的弹簧加载方式的配置是不同的,这是造成问题的原因。

//@Configuration
@EnableSwagger2
public class SwaggerConfiguration extends WebMvcConfigurationSupport

答案 2 :(得分:0)

扩展到@cristobalrosa's answer,这可能是由于Spring Boot未配置Web应用程序。例如,我的项目还有一个SwaggerConfig扩展了WebMvcConfigurationSupport

@Configuration
@EnableSwagger2
public class SwaggerConfig extends WebMvcConfigurationSupport {
    // Docket bean
    
    @Override
    protected void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("swagger-ui.html").addResourceLocations("classpath:/META-INF/resources/");
    }
}

我删除了继承和手动资源处理程序,现在工作正常。

注意:除了WebMvcConfigurationSupport之外,诸如@EnableWebMvcWebMvcConfigurer之类的内容还可能导致未使用Spring Boot的Web自动配置。

来源:Swagger Issue comment

答案 3 :(得分:0)

我有同样的错误。

我只想分享一下情况可能会给您一些提示。因此,请查看我的配置和依赖项,并阅读我链接的文章。尝试使用@EnableWebMvc而不是'WebMvcConfigurationSupport'

错误

java.lang.IllegalStateException: No primary or default constructor found for interface com.querydsl.core.types.Predicate
Caused by: java.lang.NoSuchMethodException: com.querydsl.core.types.Predicate.<init>()
    at java.base/java.lang.Class.getConstructor0(Class.java:3427)
    at java.base/java.lang.Class.getDeclaredConstructor(Class.java:2631)
    at org.springframework.web.method.annotation.ModelAttributeMethodProcessor.createAttribute(ModelAttributeMethodProcessor.java:216)

依赖项

    dependencies {
        implementation 'org.springframework.boot:spring-boot-starter-web'
        implementation "org.springframework.data:spring-data-commons"
        implementation "com.querydsl:querydsl-apt:4.3.1"
        implementation "com.querydsl:querydsl-jpa:4.3.1"
    }

从1.11开始,在spring-data-commons中可以使用Querydsl Web支持 来自https://www.baeldung.com/rest-api-search-querydsl-web-in-spring-data-jpa

Web Mvc配置

就我而言,我必须实现WebMvcConfigurer并添加@EnableWebMvc而不是WebMvcConfigurationSupport。即使扩展了@EnableWebMvc,我也不知道为什么需要WebMvcConfigurationSupport with @Configuration。我只是猜想WebMvcConfigurationSupport没有实现init() of Predicate

@Configuration
//@EnableSpringDataWebSupport // <-- doesn't necessary for me
@EnableSwagger2
@EnableWebMvc // <-- add
public class SwaggerConfig implements WebMvcConfigurer { //<-- instead of 'WebMvcConfigurationSupport'
   ...
}

来自Spring文档的QueryDSL Web支持

当在类路径上找到Querydsl时,将通过@EnableSpringDataWebSupport自动启用该功能。 https://docs.spring.io/spring-data/jpa/docs/1.9.0.RELEASE/reference/html/#core.web.type-safe

控制器

    @GetMapping
    public List<InputMethodDto.Response> getInputMethodTypeList(
            @QuerydslPredicate(root = InputMethod.class) Predicate predicate) {
        return service.getInputMethodList(predicate);
    }

存储库

public interface InputMethodRepository extends JpaRepository<yourEntity, Long>, QuerydslPredicateExecutor<yourEntity>, QuerydslBinderCustomizer<QyourEntity> {
    @Override
    default void customize(final QuerydslBindings bindings, final QyourEntity root) {
        bindings.bind(String.class).first((StringPath path, String value)-> path.eq(value));
    }
}