【问题标题】:How to use Query DSL with MongoDB in Spring Boot如何在 Spring Boot 中使用 Query DSL 和 MongoDB
【发布时间】:2018-09-15 13:03:40
【问题描述】:

我尝试在 Spring Boot 中将 Query DSL 与 MongoDB 一起使用,但出现错误。该应用程序在不使用 Query DSL for MongoDB 的库的情况下成功运行。我想使用这个库,因为我想使用更复杂的查询。代码应该可以工作,我认为某处有一个小错误。

问题是当我单击 Maven 包时出现这些错误,不幸的是我无法在此处发布所有输出:

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'hotelController' defined in file [C:\Users\dgs\IdeaProjects\springboot-mongodb\target\classes\com\dgs\springbootmongodb\controller\HotelController.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'hotelRepository': Invocation of init method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.data.mongodb.repository.support.QuerydslMongoPredicateExecutor]: Constructor threw exception; nested exception is java.lang.IllegalArgumentException: Did not find a query class com.dgs.springbootmongodb.models.QHotel for domain class com.dgs.springbootmongodb.models.Hotel!

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'hotelRepository': Invocation of init method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.data.mongodb.repository.support.QuerydslMongoPredicateExecutor]: Constructor threw exception; nested exception is java.lang.IllegalArgumentException: Did not find a query class com.dgs.springbootmongodb.models.QHotel for domain class com.dgs.springbootmongodb.models.Hotel!

Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'hotelController' defined in file [C:\Users\dgs\IdeaProjects\springboot-mongodb\target\classes\com\dgs\springbootmongodb\controller\HotelController.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'hotelRepository': Invocation of init method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.data.mongodb.repository.support.QuerydslMongoPredicateExecutor]: Constructor threw exception; nested exception is java.lang.IllegalArgumentException: Did not find a query class com.dgs.springbootmongodb.models.QHotel for domain class com.dgs.springbootmongodb.models.Hotel!

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'hotelRepository': Invocation of init method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.data.mongodb.repository.support.QuerydslMongoPredicateExecutor]: Constructor threw exception; nested exception is java.lang.IllegalArgumentException: Did not find a query class com.dgs.springbootmongodb.models.QHotel for domain class com.dgs.springbootmongodb.models.Hotel!

Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.data.mongodb.repository.support.QuerydslMongoPredicateExecutor]: Constructor threw exception; nested exception is java.lang.IllegalArgumentException: Did not find a query class com.dgs.springbootmongodb.models.QHotel for domain class com.dgs.springbootmongodb.models.Hotel!

[ERROR] Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 4.26 s <<< FAILURE! - in com.dgs.springbootmongodb.SpringbootMongodbApplicationTests
[ERROR] contextLoads(com.dgs.springbootmongodb.SpringbootMongodbApplicationTests)  Time elapsed: 0.001 s  <<< ERROR!
java.lang.IllegalStateException: Failed to load ApplicationContext
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'hotelController' defined in file [C:\Users\dgs\IdeaProjects\springboot-mongodb\target\classes\com\dgs\springbootmongodb\controller\HotelController.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'hotelRepository': Invocation of init method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.data.mongodb.repository.support.QuerydslMongoPredicateExecutor]: Constructor threw exception; nested exception is java.lang.IllegalArgumentException: Did not find a query class com.dgs.springbootmongodb.models.QHotel for domain class com.dgs.springbootmongodb.models.Hotel!
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'hotelRepository': Invocation of init method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.data.mongodb.repository.support.QuerydslMongoPredicateExecutor]: Constructor threw exception; nested exception is java.lang.IllegalArgumentException: Did not find a query class com.dgs.springbootmongodb.models.QHotel for domain class com.dgs.springbootmongodb.models.Hotel!
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.data.mongodb.repository.support.QuerydslMongoPredicateExecutor]: Constructor threw exception; nested exception is java.lang.IllegalArgumentException: Did not find a query class com.dgs.springbootmongodb.models.QHotel for domain class com.dgs.springbootmongodb.models.Hotel!
Caused by: java.lang.IllegalArgumentException: Did not find a query class com.dgs.springbootmongodb.models.QHotel for domain class com.dgs.springbootmongodb.models.Hotel!
Caused by: java.lang.ClassNotFoundException: com.dgs.springbootmongodb.models.QHotel

[ERROR] Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.21.0:test (default-test) on project springboot-mongodb: There are test failures.

这是一个酒店预订应用程序,代码如下:

酒店模型:

package com.dgs.springbootmongodb.models;

import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.index.IndexDirection;
import org.springframework.data.mongodb.core.index.Indexed;
import org.springframework.data.mongodb.core.mapping.Document;

import java.util.ArrayList;
import java.util.List;

// The Hotel is the aggregate root so this is the entity on which we will apply our annotations

    @Document(collection = "Hotels")
    public class Hotel {

        @Id
        private String id;
        private String name;

        @Indexed(direction = IndexDirection.ASCENDING)
        private int pricePerNight;
        private Address address;
        private List<Review> reviews;

        protected Hotel() {
            this.reviews = new ArrayList<>();
        }

        public Hotel(String name, int pricePerNight, Address address, List<Review> reviews) {
            this.name = name;
            this.pricePerNight = pricePerNight;
            this.address = address;
            this.reviews = reviews;
        }

        public String getId() {
            return id;
        }

        public String getName() {
            return name;
        }

        public int getPricePerNight() {
            return pricePerNight;
        }

        public Address getAddress() {
            return address;
        }

        public List<Review> getReviews() {
            return reviews;
        }
    }

HotelRepository 接口:

package com.dgs.springbootmongodb.dao;

import com.dgs.springbootmongodb.models.Hotel;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.data.mongodb.repository.Query;
import org.springframework.data.querydsl.QuerydslPredicateExecutor;
import org.springframework.stereotype.Repository;

import java.util.List;

@Repository
public interface HotelRepository extends MongoRepository<Hotel, String>, QuerydslPredicateExecutor<Hotel> {

    // findBy + PricePerNight (property name) + LessThan (filter)

    List<Hotel> findByPricePerNightLessThan(int maxPrice);

    @Query(value = "{address.city:?0}")
    List<Hotel> findByCity(String city);
}

酒店控制器:

package com.dgs.springbootmongodb.controller;

import com.dgs.springbootmongodb.dao.HotelRepository;
import com.dgs.springbootmongodb.models.Hotel;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Optional;

@RestController
@RequestMapping("/hotels")
public class HotelController {

    private HotelRepository hotelRepository;

    public HotelController(HotelRepository hotelRepository) {
        this.hotelRepository = hotelRepository;
    }

    @GetMapping("/all")
    public List<Hotel> getAllHotels() {

        List<Hotel> hotels = hotelRepository.findAll();

        return hotels;
    }

    @GetMapping("/{id}")
    public Optional<Hotel> getOneHotel(@PathVariable String id) {

        return hotelRepository.findById(id);
    }

    @PostMapping
    public Hotel create(@RequestBody Hotel hotel) {

        return hotelRepository.save(hotel);
    }

    @PutMapping
    public Hotel update(@RequestBody Hotel hotel) {

        return hotelRepository.save(hotel);
    }

    @DeleteMapping("/delete/{id}")
    public List<Hotel> delete(@PathVariable String id) {

        hotelRepository.deleteById(id);

        return hotelRepository.findAll();
    }

    @GetMapping("/price/{maxPrice}")
    public List<Hotel> getByPricePerNight(@PathVariable int maxPrice) {

        List<Hotel> hotels = hotelRepository.findByPricePerNightLessThan(maxPrice);

        return hotels;
    }

    @GetMapping("address/{city}")
    public List<Hotel> getByCity(@PathVariable String city) {

        List<Hotel> hotels = hotelRepository.findByCity(city);

        return hotels;
    }
}

这是 pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<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.dgs</groupId>
    <artifactId>springboot-mongodb</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>springboot-mongodb</name>
    <description>Demo project for Spring Boot with Mongo DB</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.5.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

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

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

        <!-- Add support for Mongo Query DSL -->

        <dependency>
            <groupId>com.querydsl</groupId>
            <artifactId>querydsl-mongodb</artifactId>
            <version>4.1.3</version>
            <exclusions>
                <exclusion>
                    <groupId>org.mongodb</groupId>
                    <artifactId>mongo-java-driver</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>

            <!-- Add plugin for Mongo Query DSL -->

            <plugin>
                <groupId>com.mysema.maven</groupId>
                <artifactId>apt-maven-plugin</artifactId>
                <version>1.1.3</version>
                <dependencies>
                    <dependency>
                        <groupId>com.querydsl</groupId>
                        <artifactId>querydsl-apt</artifactId>
                        <version>4.1.3</version>
                    </dependency>
                </dependencies>
                <executions>
                    <execution>
                        <phase>generate-sources</phase>
                        <goals>
                            <goal>process</goal>
                        </goals>
                        <configuration>
                            <outputDirectory>target/generated-sources/annotations</outputDirectory>
                            <processor>
                                org.springframework.data.mongodb.repository.support.MongoAnnotationProcessor
                            </processor>
                            <logOnlyOnError>true</logOnlyOnError>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>


</project>

更新

这是入门类:

@SpringBootApplication
public class SpringbootMongodbApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringbootMongodbApplication.class, args);
    }
}

这是应用程序的结构:

【问题讨论】:

  • 能否分享一下spring starter类的代码,你已经启用了项目的配置。
  • 您好 Archit,我只是更新问题。请帮帮我!
  • 什么是QHotel类?
  • Mongo Query DSL 的工作方式如下:交换您的实体,并且每次它找到具有该 MongoDB 注释的类时,它都会生成其他查询类,例如在这种情况下,我们有使用 @Document 注释的 Hotel 所以这是一个 MongoDB 注释,对于这个实体,它将创建一个 QHotel 类来代表查询,因此对于 Hotel 类,您可以自动生成查询 Hotel 类,然后我们可以使用这些自动生成的类来执行类型化查询。
  • 你确定你的QHotel类已经生成了吗?您正在进行的 dsl 查询是什么?

标签: java spring mongodb spring-boot querydsl


【解决方案1】:

删除目标文件夹并重新开始。

apt-maven-plugin 生成、编译源代码并添加到类路径。将插件的输出目录调整为 target/generated-sources/apt。

运行 maven 包阶段并验证 Q 类文件在目标/类位置的模型包中,并且 Q 源文件在目标/生成的源/apt 中的模型包中。

【讨论】:

  • 你成功了吗?我克隆了视频中链接的github项目,按照上面的步骤,成功执行了测试。如果您有任何问题,请告诉我。
  • 视频中链接的github项目使用的是Spring Boot 1.4.2版本,我使用的是2.0.5版本。我将版本从 2.0.5 更改为 1.4.2 并且应用程序成功运行。我认为是版本不匹配导致了这个问题。感谢您的帮助。
  • Yw。我只尝试过最新的 spring boot 版本。1.4.2 版本已经有几年了,所以你应该升级到最新的 spring boot 版本。
【解决方案2】:

我设法通过执行以下操作使您的代码正常工作:

将outputDirectory 更改为&lt;outputDirectory&gt;target/generated-sources&lt;/outputDirectory&gt;

在HotelController 中包含@Autowired

@Autowired
private HotelRepository hotelRepository;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-02-06
    • 1970-01-01
    • 1970-01-01
    • 2018-08-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-21
    相关资源
    最近更新 更多