NoSuchMethodException QueryDSL 与 Spring Boot 和 Spring Data Mongo

Posted

技术标签:

【中文标题】NoSuchMethodException QueryDSL 与 Spring Boot 和 Spring Data Mongo【英文标题】:NoSuchMethodException QueryDSL with Spring Boot & Spring Data Mongo 【发布时间】:2020-01-18 05:23:30 【问题描述】:

我正在尝试在使用 Spring Data Mongo 2.0.4.RELEASE 和 Gradle 4.10 的 Spring Boot 2.0.4.RELEASE 应用程序上实现 Query DSL。 我正在使用 Spring Tool Suite 在本地运行它。

我从多个来源(包括 Spring 数据文档)中找到了以下步骤:

创建了gradle/querydsl.gradle,其中包含以下内容以生成Q
    apply plugin: "com.ewerk.gradle.plugins.querydsl"

    sourceSets 
        main 
            java 
                srcDir "$buildDir/generated/source/apt/main"
            
        
    

    querydsl 
        springDataMongo = true
        querydslSourcesDir = "$buildDir/generated/source/apt/main"
    

    dependencies 
        compile "com.querydsl:querydsl-mongodb:4.1.4"
        compileOnly "com.querydsl:querydsl-apt:4.1.4"
    

    sourceSets.main.java.srcDirs = ['src/main/java']

从主build.gradle调用上面的gradle文件如下所示
    buildscript 

        ext  springBootVersion = "2.0.4.RELEASE" 

        repositories  mavenCentral() 

        dependencies 
            classpath "org.springframework.boot:spring-boot-gradle-plugin:$springBootVersion"
            classpath "gradle.plugin.com.ewerk.gradle.plugins:querydsl-plugin:1.0.9"
        
    

    plugins 
        id "java"
        id "eclipse"
        id "org.springframework.boot" version "2.0.4.RELEASE"
        id "io.spring.dependency-management" version "1.0.6.RELEASE"
    

    sourceCompatibility = 1.8

    repositories  mavenCentral() 

    dependencies 
        ...
        compile("org.springframework.boot:spring-boot-starter-web:$springBootVersion")
        compile("org.springframework.boot:spring-boot-starter-data-mongodb:$springBootVersion")
        ...
    

    apply from: 'gradle/querydsl.gradle'

    /* Added this because Eclipse was not able to find generated classes */
    sourceSets.main.java.srcDirs = ['build/generated/source/apt/main','src/main/java']

    compileJava.dependsOn processResources
    processResources.dependsOn cleanResources

在此之后更新Repository 注释接口如下。注意:我还使用Fragment Repository FragmentOrderRepository 进行一些自定义查询。
    public interface OrderRepository<D extends OrderDAO>
            extends EntityRepository<D>, PagingAndSortingRepository<D, String>, FragmentOrderRepository<D>, QuerydslPredicateExecutor<D> 

然后在控制器中创建了一个GET 映射,如下所示

    @RestController
    public class OrderController 
        @GetMapping(value="/orders/dsl", produces =  "application/json" )
        public ResponseEntity<List> getOrdersDSL(@QuerydslPredicate(root = OrderDAO.class) Predicate predicate, Pageable pageable, @RequestParam final MultiValueMap<String, String> parameters) 
            return (ResponseEntity<List>) orderService.getTools().getRepository().findAll(predicate, pageable);
        
    

然后在我的跑步者课程中,我添加了EnableSpringDataWebSupport 注释
    @SpringBootApplication
    @EnableSpringDataWebSupport
    public class SampleApp 
        public static void main(String[] args) 
            SpringApplication.run(SampleApp.class, args);
        
    

有了这个我的应用程序启动时没有任何错误但是当我尝试点击路径http://localhost:5057/orders/dsl?email=test@test.com

我收到一个NoSuchMethodException 和消息No primary or default constructor found for interface com.querydsl.core.types.Predicate

谁能帮忙解决这个问题?

似乎参数没有被解析为类型。

---- 2019 年 9 月 19 日更新 ----

在调试时,我发现了一个类 HandlerMethodArgumentResolverComposite,它从 argumentResolvers(类型为 HandlerMethodArgumentResolver)的列表中为给定的 MethodParameter 找到 ArgumentResolver。此列表不包含QuerydslPredicateArgumentResolver。因此它无法解决参数。

这意味着为Predicate 类型添加上述解析器的QuerydslWebConfiguration 没有被调用,这反过来表明某些AutoConfiguration 没有发生。

可能我在这里遗漏了一些注释。

【问题讨论】:

【参考方案1】:

发现我正在做的错误,在我的 Configuration 注释类上缺少 EnableWebMvc 注释。 详细信息在this 文档中。

【讨论】:

以上是关于NoSuchMethodException QueryDSL 与 Spring Boot 和 Spring Data Mongo的主要内容,如果未能解决你的问题,请参考以下文章

NoSuchMethodException 使用 datastax cassandra 映射器

java.lang.NoSuchMethodException

tomcat部署项目报错NoSuchMethodException#addServlet,addFilter

noSuchMethodException问题

部署期间出现 NoSuchMethodException

使用 Spring 上传多部分文件:NoSuchMethodException: ...CommonsMultipartFile.<init>()