Reputation: 2133
I am making a very silly mistake but not able to figure out how to fix.
I have a simple SpringBoot app using profiles, which connect to MongoDb.
My pom.xml dependencies:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.3.RELEASE</version>
</parent>
<dependencies>
<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>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
</dependencies>
My StudentController.java
@RestController
@RequestMapping("/students")
public class StudentController {
@Autowired
private StudentService studentService;
@RequestMapping(method = RequestMethod.GET)
public Collection<Student> getAllStudents(){
return studentService.getAllStudents();
}
}
My StudentService.java
@Service
public class StudentService {
@Autowired
private StudentDao studentDao;
public Collection<Student> getAllStudents(){
return this.studentDao.getAllStudents();
}
}
My StudentDao.java interface:
public interface StudentDao {
Collection<Student> getAllStudents();
}
My MongoStudentDaoImpl.java:
@Repository
@Profile("test")
public class MongoStudentDaoImpl implements StudentDao {
@Autowired
private MongoStudentRepo repo;
@Override
public Collection<Student> getAllStudents() {
return repo.findAll();
}
}
My MongoStudentRepo.java:
@Profile("test")
public interface MongoStudentRepo extends MongoRepository<Student, String> {
}
When I am trying to start the application using the "test" profile, here is the error I am seeing:
Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'studentController': Unsatisfied dependency expressed through field 'studentService'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'studentService': Unsatisfied dependency expressed through field 'studentDao'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'mongoStudentDaoImpl': Unsatisfied dependency expressed through field 'repo'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'MongoStudentRepo' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
What am I missing in here? Do I need to add an annotation to MongoStudentRepo.java
?
Thanks in advance.
Upvotes: 2
Views: 3395
Reputation: 6206
The stacktrace shows that spring is not able to autowire one of the beans MongoStudentRepo
in your MongoStudentDaoImpl.java class.From the stacktrace :
Unsatisfied dependency expressed through field 'repo'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'MongoStudentRepo' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations:
Spring throwing this exception means that the bean of MongoStudentRepo.class
is not getting created properly.
Possible solution :
@EnableJpaRepositories
to enable scanning and creation of default repository bean.For more information read here
.But if you are using xml based configuration, For xml based configuration use :
<repositories base-package="com.acme.repository" />
<repositories base-package="com.acme.repository" repository-impl-postfix="MyPostfix" />
Or using the @Configuration annotation :
@Configuration
@EnableJpaRepositories("com.acme.repositories")
class ApplicationConfiguration {
@Bean
EntityManagerFactory entityManagerFactory() {
// …
}
}
You can load this configuration only for your 'test' profile when you are using the spring default implementation.
Best read : https://docs.spring.io/spring-data/mongodb/docs/current/reference/html/#repositories.custom-implementations
Upvotes: 2
Reputation: 5142
I think for Spring Data MongoDB, adding the @EnableMongoRepositories
annotation to a @Configuration
class is all you need. Just make sure it's under the same package as your main application, or configure component scan to pick it up.
Upvotes: -1
Reputation: 2133
My apologies, I had missed out on exclude criteria I had added to the Main.java class to make another profile working. @Chrylis, thanks for your pointer.
Problematic Main.java file
@SpringBootApplication(exclude = {MongoAutoConfiguration.class, MongoDataAutoConfiguration.class, MongoRepositoriesAutoConfiguration.class})
public class Main {
public static void main(String[] args) {
SpringApplication.run(Main.class, args);
}
}
Fixed Main.java file
@SpringBootApplication(exclude = {MongoAutoConfiguration.class, MongoDataAutoConfiguration.class, MongoRepositoriesAutoConfiguration.class})
public class Main {
public static void main(String[] args) {
SpringApplication.run(Main.class, args);
}
}
Upvotes: 0
Reputation: 77167
Your interface class does not need to be annotated, as Spring Data repository interfaces are handled specially by Spring Data.
The most likely case is that your repository class isn't getting identified by Spring Data (you didn't specify a Spring Boot version or package names), in which case you may need @EnableMongoRepositories
on an @Configuration
class (your Spring Boot launcher class is also one of these).
Upvotes: 1