当前位置: 首页 > 知识库问答 >
问题:

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

汪兴旺
2023-03-14

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

MapJobRepositoryFactoryBean已被弃用

这是我的批处理配置。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();
    }
}

存储库。java类,

public interface UserRepository extends JpaRepository<User, Long> {

}

UserItemWriter中。javawrite方法中调用userRepository。saveAll()

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


共有2个答案

蒋岳
2023-03-14

MapJobRepositoryFactoryBean只建议用于测试和开发目的,而不是用于生产,它有很多问题,这就是为什么它被弃用的原因。

Spring Batch将尝试使用应用程序上下文中的数据源(如果有)。如果您不想让Spring批处理使用它来存储其状态,可以使用带有嵌入式数据库的JobRepositoryFactoryBean。最简单的方法是定义BatchConfigurerbean:

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

季骏祥
2023-03-14

我们通过定义多个数据源来解决这个问题。一个内存数据源用于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()));
    }
}

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

 类似资料:
  • 我正在使用Spring Batch和JPA处理一个批处理作业并执行更新。我正在使用默认的存储库实现。 并且我正在使用一个repository.save将修改后的对象保存在处理器中。而且,我没有在处理器或编写器中指定任何@Transactional注释。 下面是我的步骤,读取器和写入器配置:另外,我的config类是用EnableBatchProcessing注释的 在writer中,这就是我使用的

  • 我使用Spring批处理从Oracle数据库读取数据并将结果写入CSV文件。 我还需要将spring批处理元数据表与oracle数据库分开,为此,我在批处理配置中配置了两个不同的数据源(spring批处理元数据的内存数据库)。 这是我的代码: 批处理配置。JAVA 然后我的itemReader bean看起来像: 当我运行批处理时,一切正常。 但是当我尝试在我的BatchApplication中添

  • 我尝试实现Spring Batch。在这里,我试图将数据从文本文件保存到数据库中。我在处理的时候得到了NPE。 在这里,我使用JPARepository将文本文件数据保存到自定义writer类中的数据库中。此处StudentRepo为空。 为什么是空的?我尝试了另一种方法,用同样的方法手工存储在数据库中,没有问题。只有在writer类中,它是空的。

  • 我的场景是,批处理作业应该从1db(H2)读取数据,并将数据转储到另一DB(postgres)中。因此,我配置了多个数据源 我已经使用spring batch 4.2和spring boot 2.2.5编写了批处理作业。释放现在我需要为端到端测试编写测试用例。 我使用ResourcelessTransactionManager使用自定义批处理配置器来避免在内存和实际数据库中保存批处理表元数据,并且

  • 我有一个Spring Boot应用程序,通过从kafka收集数据,我正在做很多插入。我希望使用 saveAll 批处理插入来提高性能。但是很少有数据会被认为是重复的,每当在我的代码中捕获DataIntegrityViolationException时,我都会更新它们。使用批处理插入,有没有办法为每个重复的数据捕获此异常,并使用 do 更新代码进行处理?

  • 顺便说一句:我的应用程序是一些REST控制器和一些批处理作业的组合。那么使用云数据流有意义吗?如果没有,那么是否有更好的控制台管理器用于批处理作业(如重新启动、取消作业门户)等?