Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SpringBoot - BeanDefinitionOverrideException: Invalid bean definition

I am trying to setup DynamoDB locally with Spring Boot. Initially I got the setup working and was able to write/save to DynamoDB via a repository. From that point I added more classes to build my application. Now when I try to start my application, I get the following exception:

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.

I have searched SO and internet extensively but there were no any useful solution to this. The error message is misleading as well.

My project is of the following hierarchy

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);     } } 

AgentRepository.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 (Where AgentRepository is used)

@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 suggests the following: > 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.

What does null mean here? Is it because something wrong in my application config? Also how is it possible that it is already registered?

Please give me some pointers because I so confused about my next steps.

like image 924
Vino Avatar asked Dec 11 '18 11:12

Vino


People also ask

How do you override a bean in a Spring boot?

Bean Overriding Spring beans are identified by their names within an ApplicationContext. Thus, bean overriding is a default behavior that happens when we define a bean within an ApplicationContext which has the same name as another bean. It works by simply replacing the former bean in case of a name conflict.

What is Spring Main allow bean definition overriding?

Main. Allow bean definition overriding = false, which will immediately provide you with information that you have beans with the same name and there are conflicts between them. If this code is yours, and you can change the name of the Bean in any way - just do this and inject the required code.

How do you declare beans in Spring boot?

Declaring a bean. To declare a bean, simply annotate a method with the @Bean annotation. When JavaConfig encounters such a method, it will execute that method and register the return value as a bean within a BeanFactory .

How do you override a primary Bean?

Bean in TestConfiguration class will override "primary" bean. This annotations tells Spring that you want to use specific configuration for specific test, so it will override others.


2 Answers

Bean overriding has to be enabled since Spring Boot 2.1,

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

Bean Overriding

Bean overriding has been disabled by default to prevent a bean being accidentally overridden. If you are relying on overriding, you will need to set spring.main.allow-bean-definition-overriding to true.

Set

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

or yml,

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

to enable overriding again.

Edit,

Bean Overriding is based of the name of the bean not its type. e.g.

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

Will cause this error in > 2.1, by default bean names are taken from the method name. Renaming the method or adding the name attribute to the Bean annotation will be a valid fix.

like image 56
Darren Forsythe Avatar answered Oct 13 '22 17:10

Darren Forsythe


Enable bean overriding with such approach for example

@SpringBootTest(properties = "spring.main.allow-bean-definition-overriding=true") 

or

@SpringBootApplication (properties = "spring.main.allow-bean-definition-overriding=true") 
like image 40
Shell Scott Avatar answered Oct 13 '22 16:10

Shell Scott