JpaPagingItemReader - бесконечный цикл при неудачном чтении - PullRequest
0 голосов
/ 06 декабря 2018

Привет, я получаю бесконечный цикл при возникновении исключения.Что-то не так с менеджером транзакций, который я использую?Спасибо!Ниже приведены настройки моей работы

@Bean
public ItemReader<Entity> bizAppReader() {
    @SuppressWarnings("serial")
    Map<String, Object> map  = new HashMap<String, Object>() {{
      put("status", Arrays.asList(new ApplicationStatus[] {ApplicationStatus.COMPLETED, ApplicationStatus.PENDING, ApplicationStatus.INITIATE}));
    }};

    return new JpaPagingItemReaderBuilder<Entity>()
        .name("bizAppJpaReader")
        .entityManagerFactory(entityManagerFactory)
        .queryString("from Entity b where b.status in (:status)").parameterValues(map)
        .build();
  }

@Bean
public Step bizApplicatonStep(@Value("${batch.chunk_size:10}") int chunkSize,
      ItemReader<Entity> bizAppReader,
      ItemProcessor<Entity, Map<ApplicationStatus, String>> bizAppProcessor,
      ItemWriter<Map<ApplicationStatus, String>> bizAppWriter) {

    return stepBuilderFactory.get("bizApplicatonStep")
        .<Entity, Map<ApplicationStatus, String>>chunk(chunkSize).reader(bizAppReader)
        .processor(bizAppProcessor).writer(bizAppWriter)
        .faultTolerant()
          .skip(Exception.class)
          .noRollback(Exception.class)
          .skipPolicy((e, i) -> {
            log.error("Exception occurred : ", e);

            return true;
            })
          .allowStartIfComplete(true)
      .build();
  }

@Slf4j
@SpringBootApplication
@EnableBatchProcessing
public class BatchApplication  extends DefaultBatchConfigurer {

  public static void main(String[] args) throws Exception {

    ConfigurableApplicationContext context = SpringApplication.run(BatchApplication.class, args);

    JobLauncher jobLauncher = context.getBean(JobLauncher.class);
    Job job;
    JobParameters jobParameters;

    if (ArrayUtils.isNotEmpty(args) && args[0].equals("bookingJob")) {
      job = context.getBean("bookingJob", Job.class);
      jobParameters = new JobParametersBuilder()
        .addString("startMonth", args[1])
        .addString("endMonth", args[2])
        .toJobParameters();
    } else {
      job = context.getBean("bizApplicationJob", Job.class);
      jobParameters = new JobParametersBuilder().toJobParameters();
    }
    JobExecution jobExecution = jobLauncher.run(job, jobParameters);

    if (BatchStatus.FAILED.equals(jobExecution.getStatus())) {
      log.error("job execution completed exit code is : 1 ");
      System.exit(1);
    }
    log.info("job execution completed exit code is : 0 ");
  }

  @Override
  protected JobRepository createJobRepository() throws Exception {
    return new MapJobRepositoryFactoryBean(new ResourcelessTransactionManager()).getObject();
  }
}

Stacktrace:

10:13:20.657 [main] ERROR c.u.pweb.bizacct.batch.BizJobConfig - Exception occurred : 
java.lang.IllegalStateException: Transaction already active
   at org.hibernate.engine.transaction.internal.TransactionImpl.begin(TransactionImpl.java:52)

- ==================== Обновление приложения доповторить =====================

это происходит, если читателю не удалось прочитать недопустимое значение Enum из БД.

@Slf4j
@SpringBootApplication
@EnableBatchProcessing
public class DemoBatchApplication extends DefaultBatchConfigurer {

    public static void main(String[] args) {
        SpringApplication.run(DemoBatchApplication.class, args);
    }

    @Override
    public void setDataSource(DataSource dataSource) {
        super.setDataSource(null);
    }

    private final EntityManagerFactory entityManagerFactory;

  public DemoBatchApplication(EntityManagerFactory entityManagerFactory) {
    this.entityManagerFactory = entityManagerFactory;
  }

    @Override
  public PlatformTransactionManager getTransactionManager() {
    return new JpaTransactionManager(this.entityManagerFactory);
  }

}

enum

public enum ApplicationStatus {
  MA, AS, SH, CP, AA, AP
}

таблица

@Entity
@Table(name = "APP_TBL_TEST")
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class ApplicationEntity {

  @Id
  @GeneratedValue(generator = "system-uuid")
  @GenericGenerator(name = "system-uuid", strategy = "uuid2")
  @Column(name = "ID", length = 50)
  private String id;

  @Column(name = "APPLICATION_NAME", unique = true, length = 50)
  private String referenceNumber;

  @Column(name = "STATUS")
  @Enumerated(EnumType.STRING)
  private ApplicationStatus status;

}

пакетная конфигурация

@Configuration
@Slf4j
@Data
public class ApplicationBatchCfg {

  @Autowired
  public EntityManagerFactory entityManagerFactory;
  @Autowired
  public JobBuilderFactory jobBuilderFactory;
  @Autowired
  public StepBuilderFactory stepBuilderFactory;

  @Bean
  public Step applicationStep(@Value("${batch.chunk_size:5}") int chunkSize,
                              ItemReader<ApplicationEntity> appReader,
                              ItemProcessor<ApplicationEntity, String> appProcessor,
                              ItemWriter<String> appWriter){

    return stepBuilderFactory.get("applicatonStep")
      .<ApplicationEntity, String>chunk(chunkSize)
      .reader(appReader)
      .processor(appProcessor)
      .writer(appWriter)
      .faultTolerant()
      .skip(Exception.class)
      .noRollback(Exception.class)
      .skipPolicy((e, i) -> {
        log.error("Exception occurred : ", e);

        return true;
      })
      .skipLimit(5)
      .allowStartIfComplete(true)
      .build();

  }

  @Bean
  public Job applicationJob(Step applicationStep) {
    return jobBuilderFactory.get("applicationJob").incrementer(new RunIdIncrementer())
      .start(applicationStep).build();
  }

  @Bean
  public ItemReader<ApplicationEntity> appReader() {
    return new JpaPagingItemReaderBuilder<ApplicationEntity>()
      .name("appReader")
      .entityManagerFactory(entityManagerFactory)
      .queryString("from ApplicationEntity")
      .pageSize(3)
      .build();
  }

  @Bean
  public ItemProcessor<ApplicationEntity, String> appProcessor(){
    return new ItemProcessor<ApplicationEntity, String>() {
      @Override
      public String process(ApplicationEntity item) throws Exception {
        //nothing for demo only
        log.info("item {}", item);
        return null;
      }
    };
  }

  @Bean
  public ItemWriter<String> appWriter() {
    return new ItemWriter<String>() {
      @Override
      public void write(List<? extends String> items) throws Exception {
        //nothing for demo only
      }
    };
  }

}

внутри yml

spring:
  jpa:
     properties:
       hibernate:
         show_sql: true
         use_sql_comments : true
         format_sql: true
         dialect: org.hibernate.dialect.Oracle10gDialect
  datasource:
    useWallet: false
    url: jdbc:oracle:thin:@DB12397:1521:azd
    platform: oracle
    username: user
    password: pwd
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...