Компонент репозитория CRUD не найден исключение

#spring-boot #spring-data #spring-data-redis #jedis #aws-java-sdk-dynamodb

#spring-boot #spring-данные #spring-data-redis #джедаи #aws-java-sdk-dynamodb

Вопрос:

У меня есть приложение, которое подключается к AWS DynamoDB. Я пытаюсь внедрить соединение Redis с использованием Jedis в это приложение.

Однако сразу после добавления этой зависимости —

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

Я получаю эту ошибку —

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

Description:

Field userInfoRepository in org.csulb.md.service.DBService required a bean of type 'org.csulb.md.repo.UserInfoRepository' that could not be found.

The injection point has the following annotations:
- @org.springframework.beans.factory.annotation.Autowired(required=true)


Action:

Consider defining a bean of type 'org.csulb.md.repo.UserInfoRepository' in your configuration.
 

UserInfoRepository реализует CrudRepository.

Я не уверен, чего мне не хватает. Короче говоря, добавление зависимости spring-boot-starter-data-redis к этому коду приводит к этой ошибке. Без этой зависимости код работает нормально.

Ниже приведена остальная часть моего кода.

MainApp.java

 package org.csulb.md;

@SpringBootApplication
public class MainApp {

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

DynamoDBConfig.java

 package org.csulb.md.config;

@Configuration
@EnableDynamoDBRepositories(basePackages = "org.csulb.md.repo")
public class DynamoDBConfig {
    
    @Value("${amazon.dynamodb.endpoint}")
    private String amazonDynamoDBEndpoint;
 
    @Value("${amazon.aws.accesskey}")
    private String amazonAWSAccessKey;
 
    @Value("${amazon.aws.secretkey}")
    private String amazonAWSSecretKey;
    
    @Value("${amazon.aws.awsSessionToken}")
    private String awsSessionToken;
 
    @Bean
    public AmazonDynamoDB amazonDynamoDB() {
        AmazonDynamoDB amazonDynamoDB 
          = new AmazonDynamoDBClient(amazonAWSCredentials());
        
        if (!StringUtils.isEmpty(this.amazonDynamoDBEndpoint)) {
            amazonDynamoDB.setEndpoint(this.amazonDynamoDBEndpoint);
        }
        
        return amazonDynamoDB;
    }
 
    @Bean
    public AWSCredentials amazonAWSCredentials() {
        
        AWSCredentials awsCredentials = null;
        
        if(StringUtils.isEmpty(this.awsSessionToken)) {
            awsCredentials = new BasicAWSCredentials(this.amazonAWSAccessKey, this.amazonAWSSecretKey);
        } else {
            awsCredentials = new BasicSessionCredentials(this.amazonAWSAccessKey, this.amazonAWSSecretKey, this.awsSessionToken);
        }
        
        return awsCredentials;
    }
 

UserInfoRepository.java

 package org.csulb.md.repo;

@EnableScan
public interface UserInfoRepository extends CrudRepository<UserInfo, String> {}
 

GreetingController.java

 package org.csulb.md.controller;

@RestController
public class GreetingController {
    
    @Autowired
    private DBService dbService;

    @GetMapping("/getdata")
    public UserInfo greeting(@RequestParam(value = "id") String id) {
        
        UserInfo userInfo = dbService.getUserById(id);
        return userInfo;
    }
}
 

UserInfo.java

 package org.csulb.md.pojo;

@DynamoDBTable(tableName = "UserInfo")
public class UserInfo {
    
    @DynamoDBHashKey
    @DynamoDBAutoGeneratedKey
    @DynamoDBAttribute(attributeName = "id")
    private String id;
    
    @DynamoDBAttribute(attributeName = "name")
    private String name;
    
    @DynamoDBAttribute(attributeName = "location")
    private String location;

    public String getLocation() {
        return location;
    }

    public void setLocation(String location) {
        this.location = location;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
    
}
 

DBService.java

 package org.csulb.md.service;

@Component
public class DBService {
    
    Logger logger = LoggerFactory.getLogger(DBService.class);
    
    @Autowired
    private UserInfoRepository userInfoRepository;
    
    public UserInfo getUserById(String id){
        
        Optional<UserInfo> userId = userInfoRepository.findById(id);
        UserInfo userInfo = new UserInfo();
        
        if(userId.isPresent()) {
            logger.info("UserInfo found: " userId.get().getId());
            BeanUtils.copyProperties(userId.get(), userInfo);
        } else {
            logger.info("UserInfo not found: " id);
        }
        
        return userInfo;
    }

}
 

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>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.2.RELEASE</version>
        <relativePath />
    </parent>

    <groupId>org.csulb.md</groupId>
    <artifactId>dynamodb-connector</artifactId>
    <version>0.0.1</version>
    <name>dynamodb-connector</name>

    <properties>
        <java.version>1.8</java.version>
        <docker.image.prefix>springio</docker.image.prefix>
        <start-class>org.csulb.md.MainApp</start-class>
    </properties>

    <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>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <dependency>
            <groupId>com.amazonaws</groupId>
            <artifactId>aws-java-sdk-dynamodb</artifactId>
            <version>1.11.64</version>
        </dependency>

        <dependency>
            <groupId>com.github.derjust</groupId>
            <artifactId>spring-data-dynamodb</artifactId>
            <version>5.1.0</version>
        </dependency>

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

    </dependencies>

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

</project>
 

P.S — Добавление @ComponentScan(«org.csulb.md.repo») в основной класс устраняет эту ошибку, но не распознает другие компоненты, поэтому контроллер не работает. Я попытался добавить @ComponentScan(«org.csulb.md ), а также который выдает ту же ошибку, что и описанная. Я попытался добавить @Repository / @Component в UserInfoRepository и не нашел удачи.

Комментарии:

1. Прочтите это и посмотрите, проливает ли это некоторый свет на проблему. Я предполагаю, что вам нужно использовать более конкретный интерфейс репозитория.

Ответ №1:

У меня была та же проблема, которая возникла, когда я попытался использовать spring-data-dynamodb и spring data-redis . Проблема возникает из-за разрыва в реализации spring-data-dynamodb . Он не поддерживает настройку нескольких хранилищ данных. Вы также можете найти то же самое в журналах для этого: Spring Data DynamoDB does not support multi-store setups! .

Что касается решения, при использовании нескольких хранилищ данных Spring data переходит в строгий режим сканирования хранилища. Так что в моем случае я смог добавить includeFilters @EnableDynamoDBRepositories . Добавьте это, чтобы включить строгое сканирование хранилища:

 @EnableDynamoDBRepositories(basePackages = "org.csulb.md.repo",
        includeFilters = @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = Repository.class))
 

Добавьте org.springframework.stereotype.Repository аннотацию к UserInfoRepository.java классу.

Комментарии:

1. Спасибо. В итоге я создал 2 разных микросервиса, один для Redis, а другой для DynamoDB.

2. Спасибо, что вышеприведенное работает, но, похоже, проблема не возникает при загрузке Spring 2.5 и далее. Кроме того, лучший способ избежать большого количества изменений кода связан с этим @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = Repository.class)