【问题标题】:Spring Data JPA not saving to database when using Spring Batch使用 Spring Batch 时 Spring Data JPA 未保存到数据库
【发布时间】:2021-03-05 04:54:42
【问题描述】:

我有一个使用 JPA 的 Spring Boot 应用程序,它有 1 个 PostgreSQL 数据库。我正在使用 Spring Batch。场景是我正在读取文件并将数据写入 PostgreSQL 数据库。当它在数据库中创建 Spring Batch 使用的元数据表时,该程序与 PostgreSQL 一起使用。但我需要的是 Spring Boot 不创建元数据表并通过 Spring Batch 使用基于内存 Map 的作业存储库。我根本不想在数据库中创建元数据表。只需执行基于内存映射的内存。我尝试了很多答案,但都没有奏效。我明白了,

MapJobRepositoryFactoryBean 已弃用

这是我的BatchConfiguration.java 课程,

@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 类,

public interface UserRepository extends JpaRepository<User, Long> {

}

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

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

【问题讨论】:

  • 您使用的是哪个事务管理器?默认情况下,如果您在上下文中提供数据源,则 Spring Batch 使用 DataSourceTransactionManager。但是如果你使用 JPA,你需要将 Spring Batch 配置为使用 JpaTransactionManager

标签: spring spring-boot spring-data-jpa spring-batch


【解决方案1】:

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

Spring Batch 将尝试使用您的 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();
}

【讨论】:

  • 我试过这段代码。但它不起作用,它没有将数据保存到数据库,可能是它保存到内存数据库。我需要用JobRepositoryFactoryBean 配置任何东西吗?我很抱歉我缺乏这方面的知识,因为我是新手。你能帮帮我吗?
  • DefaultBatchConfigurer 将使用传递的数据源配置JobRepositoryFactoryBean。您应该将自己的 PostgreSQL 数据源定义为 bean(将由您的 JPA 存储库使用)
  • 我目前正在定义 properties 文件中的所有内容。包括datasource urlPostgreSQL。我可以配置它来解决这个问题吗?
【解决方案2】:

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

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

这允许存储库使用默认数据源以外的另一个数据源。

【讨论】:

  • 非常感谢您的回答和您的时间。
猜你喜欢
  • 2022-01-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-10
  • 2018-07-29
  • 1970-01-01
相关资源
最近更新 更多