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.
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.
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.
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 .
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.
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.
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")
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With