我正在尝试使用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和Internet,但是对此没有任何有用的解决方案。错误消息也会引起误解。
我的项目具有以下层次结构
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(使用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
在这里是什么意思?是因为我的应用程序配置有问题吗?还有怎么可能已经注册了?
请给我一些指导,因为我对下一步很困惑。
答案 0 :(得分:19)
从Spring Boot 2.1开始必须启用Bean覆盖
https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.1-Release-Notes
Bean覆盖
默认情况下禁用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
批注将是有效的解决方法。
答案 1 :(得分:11)
例如通过这种方法启用Bean覆盖
@SpringBootTest(properties = "spring.main.allow-bean-definition-overriding=true")
或
@SpringBootApplication (properties = "spring.main.allow-bean-definition-overriding=true")
答案 2 :(得分:1)
在我的例子中,有 2 个 maven 依赖是用同一个 Bean 定义的。
我在为我的所有项目发布 mvn dependency:tree
时发现了这一点。
答案 3 :(得分:1)
我遇到了同样的问题,问题是多个存储库工厂试图向它们注册所有存储库接口。就我而言,它是 JpaRepositoryFactoryBean
和 DynamoDBRepositoryFactoryBean
。正如其他答案中提到的,您可以在以下指示的日志中看到:
[INFO] Bootstrapping Spring Data DynamoDB repositories in DEFAULT mode.
[INFO] Finished Spring Data repository scanning in 64ms. Found 2 DynamoDB repository interfaces.
[INFO] Bootstrapping Spring Data JPA repositories in DEFAULT mode.
解决方案是:
@SpringBootApplication
@EnableAutoConfiguration(exclude = {
DataSourceAutoConfiguration.class,
DataSourceTransactionManagerAutoConfiguration.class,
HibernateJpaAutoConfiguration.class})
不同版本的配置可能会有所不同,具体取决于您的应用程序中的存储库数量。阅读有关 Multi-Repository-configuration
的内容可能会有所帮助答案 4 :(得分:0)
我认为MongoDB也有同样的问题。至少错误消息看起来完全一样,而且我也只有一个MongoDB存储库,如下所示:
public interface MyClassMongoRepository extends MongoRepository<MyClass, Long> {
}
该问题是由以前在另一个数据库中使用过的MyClass类引起的。在创建MongoRepository之前,Spring默默地创建了一些JpaRepository。两个存储库的名称相同,导致冲突。
解决方案是制作MyClass的副本,将其移动到MongoRepository的程序包中,并删除所有JPA特定的注释。
答案 5 :(得分:0)
当我试图通过spring-data-jdbc将PostgreSQL数据库添加到已经使用MongoDB的现有项目时,我偶然发现了同一问题。
似乎问题出在两个模块(spring-mongo和spring-jdbc)都扫描了MongoDB和PostgreSQL的存储库。他们俩都尝试创建一些bean并发生冲突。
在我的情况下,MongoDB存储库和PostgreSQL存储库位于同一软件包中。
接受的答案为我解决了问题- 但是我从启动日志中得到了一些提示:
Finished Spring Data repository scanning in 319ms. Found 4 repository interfaces
Finished Spring Data repository scanning in 319ms. Found 5 repository interfaces
这很奇怪,因为我只有1个PostgreSQL存储库和4个MongoDB存储库。
我将PostgreSQL信息库移到了不同于MongoDB信息库的程序包中,并将PostgreSQL信息库的基本程序包配置为新程序包。 就我而言:
@EnableJdbcRepositories(basePackageClasses = MyOnlyPostgreSQLRepository.class) // TODO: Use the real package or a dedicated base class
这为我解决了这个问题(没有为bean覆盖设置属性-我更喜欢)。启动日志还显示了正确数量的存储库(1和4)。