I try to learn how to use Query DSL with MongoDB in Spring Boot and I get an error. I found this app on youtube, the single difference is that he use the old interface QueryDslPredicateExecutor and I'm using the new one QuerydslPredicateExecutor. The app is working successfully without without using the library for Query DSL for MongoDB. And I want to use this library because I want to use more complex queries. The code should work, I think there is a little mistake somewhere.
The problem is when I click Maven package I get these errors, unfortunatelly I can't post all the output here:
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.
It is a hotel booking app and this is the code:
The Hotel model:
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; } }
The HotelRepository interface:
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); }
The HotelController:
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; } }
This is the 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>
Update
This is the starter class:
@SpringBootApplication public class SpringbootMongodbApplication { public static void main(String[] args) { SpringApplication.run(SpringbootMongodbApplication.class, args); } }
This is the structure of the app:
And here is the tutorial from youtube: https://www.youtube.com/watch?v=Hu-cyytqfp8
2 Answers
Answers 1
I managed to make your code work by doing the following:
Change the outputDirectory
to <outputDirectory>target/generated-sources</outputDirectory>
Include @Autowired
in HotelController
@Autowired private HotelRepository hotelRepository;
Answers 2
Remove the target folder and start over.
apt-maven-plugin generates, compiles source and adds to classpath. Adjust the plugin's output directory to target/generated-sources/apt.
Run the maven package phase and verify Q class files are inside models packages in targets/classes location and Q source files are inside models package in target/generated-sources/apt.
0 comments:
Post a Comment