1. ホーム
  2. java

SpringBoot - BeanDefinitionOverrideException。無効なビーン定義

2023-08-08 05:36:17

質問

Spring BootでDynamoDBをローカルにセットアップしようとしています。当初はセットアップがうまくいき、リポジトリ経由でDynamoDBに書き込み/保存ができるようになりました。そこからさらにクラスを追加して、アプリケーションを構築しました。現在、アプリケーションを起動しようとすると、以下のような例外が発生します。

org.springframework.beans.factory.support.BeanDefinitionOverrideException: Invalid bean definition with name 'agentRepository' defined in null: Cannot register bean definition [Root bean: class [org.socialsignin.spring.data.dynamodb.repository.support.DynamoDBRepositoryFactoryBean]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null] for bean 'agentRepository': There is already [Root bean: class [org.socialsignin.spring.data.dynamodb.repository.support.DynamoDBRepositoryFactoryBean]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null] bound.

SOやネットで散々検索しましたが、これといった有用な解決策はありませんでした。エラーメッセージも誤解を招くものです。

私のプロジェクトは以下のような階層になっています。

ai.test.as
  - as
      - agent
          - business
          - intent
          - exception
          - Agent.java
          - AgentDTO.java
          - AgentRespository.java
          - AgentController.java
          - AgentService.java
          - AgentServiceImpl.java
  - config
     - DynamoDBConfig.java

DynamoDBConfig.java

package ai.test.as.config;

import ai.test.as.agent.AgentRepository;
import ai.test.as.agent.intent.template.TemplateRepository;
import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDB;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient;
import org.socialsignin.spring.data.dynamodb.repository.config.EnableDynamoDBRepositories;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@EnableDynamoDBRepositories(basePackageClasses = {AgentRepository.class})
public class DynamoDBConfig
{
    @Value("${aws.dynamodb.endpoint}")
    private String dynamoDBEndpoint;

    @Value("${aws.auth.accesskey}")
    private String awsAccessKey;

    @Value("${aws.auth.secretkey}")
    private String awsSecretKey;

    @Bean
    public AmazonDynamoDB amazonDynamoDB()
    {
        AmazonDynamoDB dynamoDB = new AmazonDynamoDBClient(getAwsCredentials());
        dynamoDB.setEndpoint(dynamoDBEndpoint);

        return dynamoDB;
    }

    @Bean
    public AWSCredentials getAwsCredentials()
    {
        return new BasicAWSCredentials(awsAccessKey, awsSecretKey);
    }
}

エージェントリポジトリ.java

package ai.test.as.agent;

import ai.test.as.agent.Agent;
import org.socialsignin.spring.data.dynamodb.repository.EnableScan;
import org.springframework.data.repository.CrudRepository;

@EnableScan
public interface AgentRepository extends CrudRepository<Agent, String>
{
}

AgentController.java (AgentRepositoryが使用される場所)

@RestController
@RequestMapping(value = "/v1/agents")
public class AgentController
{
    @Autowired
    private AgentRepository agentRepository;

    @RequestMapping(value = "/test", method = RequestMethod.POST)
    public void test()
    {
        Agent agent = new Agent();
        agent.setAgentNumber("123456");
        agent.setId(1);

        agentRepository.save(agent);
    }
}

Springは次のように提案しています。 > The bean 'agentRepository', defined in null, could not be registered. A bean with that name has already been defined in null and overriding is disabled .

何をするかというと null は何を意味するのでしょうか?私のアプリケーションの設定に何か問題があるからでしょうか?また、すでに登録されているのはどうしてでしょうか?

私は私の次のステップについて非常に混乱しているので、私にいくつかのポインタを与えてください。

どのように解決するのですか?

Spring Boot 2.1以降、Beanのオーバーライドを有効にする必要があります。

https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.1-Release-Notes

<ブロッククオート

ビーンのオーバーライド

Beanのオーバーライドは、誤ってBeanがオーバーライドされるのを防ぐため、デフォルトで無効化されています。オーバーライドに依存している場合、spring.main.allow-bean-definition-overridingをtrueに設定する必要があります。

設定する

spring.main.allow-bean-definition-overriding=true

またはymlを使用します。

spring:
   main:
     allow-bean-definition-overriding: true

で再度上書きできるようにします。

編集してください。

Beanのオーバーライドは、その型ではなくBeanの名前に基づきます。例えば

@Bean
public ClassA class(){
   return new ClassA();
}

@Bean
public ClassB class(){
   return new ClassB();
}

2.1では、デフォルトでBean名はメソッド名から取得されるため、このエラーが発生します。メソッド名を変更したり name 属性に Bean アノテーションは有効な修正となります。