“BasicBatchConfigurer”已保护访问 - Spring Batch/Spring Boot 未将数据持久化到数据库

Posted

技术标签:

【中文标题】“BasicBatchConfigurer”已保护访问 - Spring Batch/Spring Boot 未将数据持久化到数据库【英文标题】:"BasicBatchConfigurer" has protected access - Spring Batch/Spring Boot not persisting data to database 【发布时间】:2021-07-09 18:35:42 【问题描述】:

我最近将我的 spring boot/batch Java 应用程序从 spring-boot/spring-framework(分别)1.xx/4.xx 迁移到 => 2.xx/5.xx(2.2.4/5.2.3 到请明确点)。问题是事务/实体管理器肯定有问题(在我看来),因为当从我的数据库持久层的 JpaRepository 类调用 .saveAll() 方法时,它会跳转到 SpringAOP 框架/库代码和进入无限循环。我看到它从方法(invoke())返回一个“DefaulTransaction”对象。我在 1.x.x/4.x.x 上的应用程序在工作时会在此处返回我的实体的实际 ArrayList。我正在使用spring-boot-starterspring-boot-starter-webspring-boot-starter-data-jpaspring-boot-starter-batchhibernate/hibernate-envers/hibernate-envers/hibernate-entitymanager(当然还有许多其他依赖项,如果您希望我列出它们,请告诉我)。

经过一些研究,我发现人们说 Spring Batch @EnableBatchProcessing 注释设置了一个默认事务管理器,如果我使用 JPA 可能会导致问题。参考: https://github.com/spring-projects/spring-boot/issues/2363

wilkinsona 建议在我的 @Configuration 类中定义这个 Bean:

@Bean
public BatchConfigurer batchConfigurer(DataSource dataSource, EntityManagerFactory entityManagerFactory) 
    return new BasicBatchConfigurer(dataSource, entityManagerFactory);
   

执行此操作时出现错误,因为它说BasicBatchConfigurer() 具有受保护的访问权限。实例化它的最佳方法是什么?

我还看到有人说删除 @EnableBatchProcessing 注释可以解决数据库持久性问题,但是当我删除它时,我无法自动装配我的 JobBuilderFactoryStepBuilderFactory强>。有没有办法删除注释并在我的代码中获取这些对象,这样我至少可以测试它是否有效?对不起,我不是 Spring Batch/Spring 的大师。

在我的@Configuration 课程中,我使用的是PlatformTransactionManager。我正在设置我的 JobRepository 是这样的。:

@Bean
 public JobRepository jobRepository(PlatformTransactionManager transactionManager,
                                                @Qualifier("dataSource") DataSource dataSource) throws Exception 
        JobRepositoryFactoryBean jobRepositoryFactoryBean = new JobRepositoryFactoryBean();
        jobRepositoryFactoryBean.setDataSource(dataSource);
        jobRepositoryFactoryBean.setTransactionManager(transactionManager);
        jobRepositoryFactoryBean.setDatabaseType("POSTGRES");
        return jobRepositoryFactoryBean.getObject();
    

如果需要,我可以提供任何其他信息。另一个问题是 - 如果我基本上使用相同的代码、事务管理器、实体管理器等。我的代码在 1.x.x 上工作的时间如何?我的 pom.xml 中的某个地方是否存在错误的依赖项,以至于我的新迁移代码使用了错误的方法或来自错误的依赖项?

【问题讨论】:

【参考方案1】:

默认情况下,@EnableBatchProcessing 将 Spring Batch 配置为使用 DataSourceTransactionManager,如果您提供 DataSource。该事务管理器对您的 JPA 上下文一无所知。所以如果你想使用JPA存储库来保存数据,你需要配置Spring Batch使用JpaTransactionManager

现在为了提供自定义事务管理器,您需要注册一个BatchConfigurer 并覆盖getTransactionManager() 方法,例如:

@Bean
public BatchConfigurer batchConfigurer(DataSource dataSource) 
    return new DefaultBatchConfigurer(dataSource) 
        @Override
        public PlatformTransactionManager getTransactionManager() 
            return new JpaTransactionManager();
        
    ;

这在Configuring A Job 部分和@EnableBatchProcessing 的Javadoc 中进行了解释。

【讨论】:

以上是关于“BasicBatchConfigurer”已保护访问 - Spring Batch/Spring Boot 未将数据持久化到数据库的主要内容,如果未能解决你的问题,请参考以下文章

STM32F407 读保护,写保护,解锁过程芯片已设置读保护,无法读取更多信息

iOS 数据保护不适用于已安装的应用程序

LinQ 试图读取或写入受保护的内存。这通常表明其他内存已损坏

使用 stunnel 和 Ratchet 保护 websocket。连接已关闭

尝试读取或写入受保护的内存。这通常表明其他内存已损坏

尝试读取或写入受保护的内存。这通常表明其他内存已损坏。在 C++ DLL 中