我正在尝试使用Spring Batch在Postgres数据库和MongoDB之间迁移一些数据。我配置了一个非常简单的ItemReader、ItemProcessor和ItemWriter,并且一切都按预期运行。但是,如果我切换到RepositoryItemReader,我会收到以下错误:
java.lang.IllegalStateException: Already value [org.springframework.jdbc.datasource.ConnectionHolder@684430c1] for key [HikariDataSource (HikariPool-1)] bound to thread
如果我理解正确的话,EntityManager或TransactionManager有问题,但我不知道是什么问题,也不知道为什么它与一个不与存储库一起工作的简单ItemReader一起工作,但它使用的是相同的数据源。
我将非常感激任何帮助。
以下是我的源数据库配置:
package com.example.batch.primary;
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
entityManagerFactoryRef = "primaryEntityManagerFactory",
transactionManagerRef = "primaryTransactionManager",
basePackages = {"com.example.batch.primary"}
)
public class PrimaryDBConfig {
@Bean(name = "primaryDataSource")
@Primary
public DataSource primaryDatasource(){
DataSourceBuilder dataSourceBuilder = DataSourceBuilder.create()
.driverClassName("org.postgresql.Driver")
.url("jdbc:postgresql://localhost:5432/postgres")
.username("test")
.password("test");
return dataSourceBuilder.build();
}
@Bean(name = "primaryEntityManagerFactory")
@Primary
public LocalContainerEntityManagerFactoryBean primaryEntityManagerFactory(EntityManagerFactoryBuilder builder,
@Qualifier("primaryDataSource")
DataSource primaryDataSource){
return builder.dataSource(primaryDataSource)
.packages("com.example.batch.primary")
.build();
}
@Bean(name = "primaryTransactionManager")
public PlatformTransactionManager primaryTransactionManager(
@Qualifier("primaryEntityManagerFactory") EntityManagerFactory primaryEntityManagerFactory)
{
return new JpaTransactionManager(primaryEntityManagerFactory);
}
}
以下是MongoDB的配置:
package com.example.batch.secondary;
@EnableMongoRepositories(basePackages = "com.example.batch.secondary")
@Configuration
public class MongoDBConfig {
@Bean
public MongoClient mongo() {
ConnectionString connectionString = new ConnectionString("mongodb+srv://mongoadmin:blablabla.mongodb.net/?retryWrites=true&w=majority");
MongoClientSettings mongoClientSettings = MongoClientSettings.builder()
.applyConnectionString(connectionString)
.build();
return MongoClients.create(mongoClientSettings);
}
@Bean
public MongoTemplate mongoTemplate() throws Exception {
return new MongoTemplate(mongo(), "test");
}
}
以下是储存库项目读取器:
package com.example.batch.stepcomponents;
@Component
public class RepositoryReader extends RepositoryItemReader<Partner> {
public RepositoryReader(@Autowired PartnerRepository partnerRepository){
setRepository(partnerRepository);
setPageSize(1);
setSort(Map.of("id", Sort.Direction.ASC));
setMethodName("findAll");
}
}
批配置:
@Configuration
@EnableBatchProcessing
public class BatchConfig {
@Autowired
public JobBuilderFactory jobBuilderFactory;
@Autowired
public StepBuilderFactory stepBuilderFactory;
@Autowired
RepositoryReader repositoryReader;
@Autowired
CustomWriter customWriter;
@Autowired
CustomProcessor customProcessor;
@Bean
public Job createJob() {
return jobBuilderFactory.get("MyJob")
.incrementer(new RunIdIncrementer())
.flow(createStep())
.end()
.build();
}
@Bean
public Step createStep() {
return stepBuilderFactory.get("MyStep")
.<Partner, Student> chunk(1)
.reader(repositoryReader)
.processor(customProcessor)
.writer(customWriter)
.build();
}
}
2条答案
按热度按时间hpcdzsge1#
所以我试着取出EntityManagerFactory和TransactionManager,现在它工作了。我猜它们在启动服务器时已经自动初始化了。
是的,默认情况下,如果您提供了一个
DataSource
bean,Spring Batch将使用一个DataSourceTransactionManager
,而不是您所期望的JPA bean。为了使用JPA事务管理器,您需要配置一个自定义的
BatchConfigurer
并覆盖getTransactionManager
,如下所示:请注意,从v5开始将不再需要此功能,请参阅:
您还可以在步骤上设置JPA事务管理器:
tv6aics12#
如果未定义其他TransactionManager,则将“spring-data-jpa”添加为依赖项将自动配置JpaTransactionManager