Search code examples
mongodbspring-bootapache-kafkamicroservices

Parameter 0 of constructor required a bean of type error


I'm getting this error and haven't found a solution on SO or the internet that will help me clear it up.

***************************
APPLICATION FAILED TO START
***************************

Description:

Parameter 0 of constructor in com.microservices.registration.service.RegistrationService required a bean of type 'com.microservices.registration.repository.RegistrationRepository' that could not be found.
   
Action:

Consider defining a bean of type 'com.microservices.registration.repository.RegistrationRepository' in your configuration.
   
Process finished with exit code 0

I have a multi-microservices application and this service handles the registration portion. I have Respository annotation for the respository and proper Spring annotations throughout. I can't figure out what's wrong. Maybe another set of eyes can discover what I'm missing.

RegistrationRepository

package com.microservices.registration.repository;

import com.microservices.registration.model.RegistrationUser;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface RegistrationRepository extends MongoRepository<RegistrationUser, String> {

    RegistrationUser findByEmail(String email);
}

RegistrationService

package com.microservices.registration.service;

import com.microservices.registration.model.RegistrationUser;
import com.microservices.registration.repository.RegistrationRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Service;

import java.util.List;


@Service
public class RegistrationService {

    private final RegistrationRepository registrationRepository;
    private final KafkaTemplate<String, RegistrationUser> kafkaTemplate;
    private static final String GROUP_ID_CONFIG = "registrationGroup";

    private enum Status {
        PENDING,
        APPROVED,
        REJECTED
    }

    @Value("${spring.kafka.topic.name}")
    private String kafkaTopic;

    @Autowired
    public RegistrationService(RegistrationRepository registrationRepository,
                               KafkaTemplate<String, RegistrationUser> kafkaTemplate){
        this.registrationRepository = registrationRepository;
        this.kafkaTemplate = kafkaTemplate;
    }
    public void registerUser(RegistrationUser registrationUser) {
        try {
            RegistrationUser pendingUser = registrationRepository.findByEmail(registrationUser.getEmail());
            if (pendingUser == null) {
                registrationUser.setStatus(String.valueOf(Status.PENDING));
                //registrationRepository.save(registrationUser); don't save users to db who aren't approved yet.
                kafkaTemplate.send(kafkaTopic, registrationUser);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
    @Autowired
    public List<RegistrationUser> getAllUsers() {
        return registrationRepository.findAll();
    }

    /**
     * To find users in Kafka with a PENDING status, consume the messages
     * from the Kafka topic and filter the messages based on their status field.
     * Once the user is updated to APPROVED, send the message to the Kafka topic
     * and save the user to the database.
     */
    @KafkaListener(topics = "registrationUsers", groupId = GROUP_ID_CONFIG)
    public void approveUser(RegistrationUser registrationUser) {
        try {
            if(registrationUser.getStatus().equals(String.valueOf(Status.PENDING))) {
                registrationUser.setStatus(String.valueOf(Status.APPROVED));
                registrationRepository.save(registrationUser);
                kafkaTemplate.send(kafkaTopic, registrationUser);
            } else {
                registrationUser.setStatus(String.valueOf(Status.REJECTED));
                kafkaTemplate.send(kafkaTopic, registrationUser);
        }

    } catch(Exception e) {
        e.printStackTrace();
    }

}
    public RegistrationUser getUserByEmail(String email) {
        return registrationRepository.findByEmail(email);
    }

    public void deleteUser(String Id) {
        registrationRepository.deleteById(Id);
    }

}

RegistrationApplication

package com.microservices.registration;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

@SpringBootApplication
@EnableEurekaClient
public class RegistrationApplication {

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

    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}



Application.properties

spring.application.name=application
spring.kafka.topic.name=registrationUser
spring.kafka.bootstrap-servers=localhost:9092
spring.kafka.consumer.group-id=registrationUser
spring.data.mongodb.uri=mongodb://localhost:27017/registration
spring.data.mongodb.database=registration
logging.level.root=DEBUG
logging.level.org.springframework.data.mongodb.core.MongoTemplate=DEBUG
logging.level.org.springframework.data.mongodb.core.MongoExceptionTranslator=DEBUG
spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration

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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.microservices</groupId>
        <artifactId>microservices</artifactId>
        <version>1.1-SNAPSHOT</version>
        <relativePath>../pom.xml</relativePath>
    </parent>

    <artifactId>registration-service</artifactId>

    <dependencies>
        <dependency>
            <groupId>org.hibernate.orm</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>6.1.7.Final</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

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

        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure-processor</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>
        <dependency>
            <groupId>org.testcontainers</groupId>
            <artifactId>junit-jupiter</artifactId>
            <scope>test</scope>
            <version>1.17.6</version>
        </dependency>
        <dependency>
            <groupId>org.testcontainers</groupId>
            <artifactId>mongodb</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.mongodb</groupId>
            <artifactId>mongo-java-driver</artifactId>
            <version>3.12.12</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.kafka</groupId>
            <artifactId>spring-kafka</artifactId>
            <version>3.0.4</version>
        </dependency>
        <dependency>
            <groupId>org.apache.kafka</groupId>
            <artifactId>kafka-streams</artifactId>
            <version>3.4.0</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <version>${spring.boot.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.kafka</groupId>
            <artifactId>spring-kafka-test</artifactId>
            <version>3.0.4</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.sun.jersey.contribs</groupId>
            <artifactId>jersey-apache-client4</artifactId>
            <version>1.19.4</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
    </dependencies>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.testcontainers</groupId>
                <artifactId>testcontainers-bom</artifactId>
                <version>1.17.6</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>${spring.boot.version}</version>
            </plugin>
        </plugins>
    </build>
    <repositories>
        <repository>
            <id>spring-snapshots</id>
            <name>Spring Snapshots</name>
            <url>https://repo.spring.io/snapshot</url>
        </repository>
    </repositories>
</project>

Solution

  • To use repository, you have to add @EnableMongoRepositories. For example:

    @EnableMongoRepositories(basePackages = "com.microservices.registration.repository")
    
    

    if no base package specified, it will trigger scanning of the package of annotated class.