«BasicBatchConfigurer» имеет защищенный доступ — пакет Spring/Загрузка Spring не сохраняет данные в базе данных

#java #spring-boot #hibernate #spring-batch #spring-transactions

Вопрос:

Недавно я перенес свое Java-приложение spring boot/batch из spring-boot/spring-framework (соответственно) 1.x.x/4.x.x в => 2.x.x/5.x.x (2.2.4/5.2.3, если быть точным). Проблема в том, что что-то определенно не так (на мой взгляд) с менеджером транзакций/сущностей, так как, когда .saveAll() метод вызывается из JpaRepository класса моего уровня сохранения базы данных, он переходит в фреймворк SpringAOP/библиотечный код и в бесконечный цикл. Я вижу, что он возвращает объект «defaulttransaction» из метода (invoke()). Мое приложение на 1.x.x/4.x.x, когда оно работало, возвращало бы фактический список ArrayList здесь моих сущностей. Я использую spring-boot-starter , spring-boot-starter-web , spring-boot-starter-data-jpa , spring-boot-starter-batch , и hibernate / hibernate-envers / hibernate-entitymanager (также, конечно, много других зависимостей, дайте мне знать, если вы хотите, чтобы я их перечислил).

После некоторых исследований я обнаружил, что люди говорят, что @EnableBatchProcessing в аннотации Spring Batch устанавливается менеджер транзакций по умолчанию, что, если я использую JPA, может вызвать проблемы. Ссылка: https://github.com/spring-projects/spring-boot/issues/2363

уилкинсона предложила определить этот боб в моем @Configuration классе:

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

Я получаю ошибку, когда делаю это, потому что в нем говорится BasicBatchConfigurer() , что доступ защищен. Каков наилучший способ создать этот экземпляр?

Я также видел, как некоторые люди говорили, что удаление @EnableBatchProcessing аннотации устраняет проблему с сохранением базы данных, но когда я удаляю это, я теряю возможность автоматически подключать свой JobBuilderFactory и StepBuilderFactory. Есть ли способ удалить аннотацию и включить эти объекты в мой код, чтобы я мог хотя бы проверить, работает ли это? Извините, я не совсем мастер с весенней партией/весной.

В своем @Configuration классе я использую PlatformTransactionManager . Я создаю свою вакансию примерно так.:

 @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 для использования a DataSourceTransactionManager , если вы предоставляете a DataSource . Этот менеджер транзакций ничего не знает о вашем контексте JPA. Поэтому, если вы хотите использовать репозиторий JPA для сохранения данных, вам необходимо настроить пакет Spring для использования JpaTransactionManager .

Теперь, чтобы предоставить пользовательский менеджер транзакций, вам нужно зарегистрировать BatchConfigurer и переопределить getTransactionManager() метод, что-то вроде:

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

Это объясняется в разделе Настройка задания и в разделе Javadoc @EnableBatchProcessing .