Spring 使用 Spring 批处理时数据 JPA 未保存到数据库

Spring Data JPA not saving to database when using Spring Batch

我有一个 Spring 使用 JPA 的启动应用程序,它有 1 个 PostgreSQL 数据库。我正在使用 Spring 批处理。场景是我正在读取文件并将数据写入 PostgreSQL 数据库。该程序在创建 Spring Batch 在数据库中使用的元数据表时与 PostgreSQL 配合使用。但我需要的是 Spring 引导不创建元数据表并通过 Spring 批处理使用内存中基于地图的作业存储库。我根本不想在数据库中创建元数据表。只需要在内存中基于 Map 执行。我尝试了很多答案,但其中 none 有效。我明白了,

MapJobRepositoryFactoryBean is deprecated

这是我的 BatchConfiguration.java class,

@Configuration
@EnableBatchProcessing
public class BatchConfiguration {

    private @Autowired JobBuilderFactory jobBuilderFactory;
    private @Autowired StepBuilderFactory stepBuilderFactory;
    private @Autowired UserItemReader userItemReader;
    private @Autowired UserItemProcessor userItemProcessor;
    private @Autowired UserItemWriter userItemWriter;

    @Bean
    public Step importUsersStep() {
        return stepBuilderFactory.get("STEP-01")
                .<User, User>chunk(10)
                .reader(userItemReader)
                .processor(userItemProcessor)
                .writer(userItemWriter)
                .build();
    }

    @Bean
    public Job importUsersJob() {
        return jobBuilderFactory.get("JOB-IMPORT")
                .flow(importUsersStep())
                .end()
                .build();
    }
}

Repository.java class,

public interface UserRepository extends JpaRepository<User, Long> {

}

UserItemWriter.javawrite 方法中我调用 userRepository.saveAll();

那么我怎样才能使它与基于内存映射一起工作,而且因为我正在使用 Spring Data JPA 将用户保存到数据库中所以保存也应该没有任何问题,因为当我尝试一些方法时,我没有看到任何提交给 PostgreSQL 的内容,我认为甚至用户数据也提交给了内存中的映射。所以有人可以帮助我吗?提前致谢。

MapJobRepositoryFactoryBean 仅推荐用于测试和开发目的,不用于生产用途,它有很多问题,这就是它被弃用的原因。

Spring 批处理将尝试使用 ApplicationContext 中的 DataSource 如果您 有一个。如果您不希望 Spring Batch 使用它来存储其状态,您可以将 JobRepositoryFactoryBean 与嵌入式数据库一起使用。最简单的方法是定义一个 BatchConfigurer bean:

@Bean
public BatchConfigurer configurer() {
    return new DefaultBatchConfigurer(dataSource());
}

public DataSource dataSource(){
    return new EmbeddedDatabaseBuilder()
            .setType(EmbeddedDatabaseType.HSQL)
            .addScript("classpath:org/springframework/batch/core/schema-drop-hsqldb.sql")
            .addScript("classpath:org/springframework/batch/core/schema-hsqldb.sql")
            .build();
}

我们通过定义多个数据源来解决这个问题。一个内存数据源用于 Spring 批处理元数据,另一个或多个数据源用于作业,具体取决于配置。

# for spring batch metadata
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=password

# for jobs
job.datasource.url=jdbc:postgresql://localhost:5432/postgres
job.datasource.username=user
job.datasource.password=password

我们像

一样手动创建数据源
    @Bean
    @Primary
    @ConfigurationProperties("spring.datasource")
    public DataSourceProperties mysqlDataSourceProperties() {
        return new DataSourceProperties();
    }

还有一个。

@Configuration
@EnableJpaRepositories(basePackages = "your.package.name",
        entityManagerFactoryRef = "postgresEntityManagerFactory",
        transactionManagerRef= "postgresTransactionManager")
public class PostgresDataConfig {

    @Bean
    @ConfigurationProperties("postgres.datasource")
    public DataSourceProperties postgresDataSourceProperties() {
        return new DataSourceProperties();
    }

    @Bean(name = "postgresEntityManagerFactory")
    public LocalContainerEntityManagerFactoryBean postgresEntityManagerFactory(
            EntityManagerFactoryBuilder builder) {
        return builder
                .dataSource(postgresDataSource())
                .packages("com.bimurto.multipledatasource.postgres")
                .build();
    }

    @Bean(name = "postgresTransactionManager")
    public PlatformTransactionManager postgresTransactionManager(
            final @Qualifier("postgresEntityManagerFactory") LocalContainerEntityManagerFactoryBean entityManagerFactory) {
        return new JpaTransactionManager(Objects.requireNonNull(entityManagerFactory.getObject()));
    }
}

这允许存储库使用默认数据源以外的其他数据源。