Ошибка с Spring batch Classifier Composite Item Writer

Я должен в основном создавать несколько файлов xml для каждого file_id для каждой валюты (например, usd,zar ect), все эти транзакции находятся в одной таблице БД. Должен ли я создавать составной писатель для каждой валюты, и на моем обработчике элементов я фильтрую для каждой отдельной валюты, которую я считываю из БД. или Могу ли я использовать несколько шагов для каждой валюты для каждого file_id? Я изо всех сил пытался найти решение Springbatch по этому поводу.

Имя файла ресурса будет отличаться для каждого файла и валюты. Например, я могу получить file_id=1 currency=USD должен быть 1 файл "USD20051701 с 01 последовательностью файлов". Я также могу получить два файла file_id 1 и 2 для Currency ='ZAR', и это должны быть два файла 'ZAR20051701' и 'ZAR20051702' 01 и 02 файловых последовательностей.

Я использовал эту ссылку в качестве руководства из одного из сообщений. /questions/46668012/sozdanie-logiki-vnutri-spring-batch-s-pomoschyu-tasklet-ili-vnutri-compositeitemwriter/46668025#46668025

Я получаю этот файл журналатрассировки

Пожалуйста, помогите, я застрял, пытаясь отладить снимок экрана журнала. Я написал классификатор для записи в 3 разных файла для каждой валюты, но получаю сообщение об ошибке

@Bean
public ClassifierCompositeItemWriter<Settlement> classifierCompositeItemWriter
        (       ItemWriter<Settlement> ZMWItemWriter,
                ItemWriter<Settlement> USDItemWriter, 
                ItemWriter<Settlement> ZARItemWriter
    ) {
    ClassifierCompositeItemWriter<Settlement> classifierCompositeItemWriter = new ClassifierCompositeItemWriter<>();
    classifierCompositeItemWriter.setClassifier(new Classifier<Settlement, ItemWriter<? super Settlement>>() {
        
        @Override
        public ItemWriter<? super Settlement> classify(Settlement settlement) {
            
            List<SettlementHeader> settlementheader= new ArrayList<SettlementHeader>();
            SettlementHeader header = new SettlementHeader ();
            settlementheader.add(header);
            settlement.setSettlementHeader(settlementheader);
            
        if (header.getCurrency().equalsIgnoreCase("ZMW")) {
            return ZMWItemWriter;
        } 
        else if (header.getCurrency().equalsIgnoreCase("USD")) {
            return USDItemWriter;
        }
        else {
            return ZARItemWriter;}
        }
    });
    return classifierCompositeItemWriter;
}

    @Qualifier ("USDItemWriter")
    @Bean(destroyMethod="")
   public NoRootStaxEventItemWriter<Settlement> USDItemWriter() throws Exception {
    NoRootStaxEventItemWriter<Settlement> ItemWriter = new NoRootStaxEventItemWriter<>();
    FileSystemResource resource = new FileSystemResource("FileUSD1.xml");
    ItemWriter.setName("USDItemWriter");
       ItemWriter.setResource(resource);
       marshaller.setPackagesToScan("com.model");
       ItemWriter.setMarshaller(marshaller);
       ItemWriter.afterPropertiesSet();
       return ItemWriter;
   }

@Primary
@Qualifier("ZARItemWriter") 
@Bean(destroyMethod="")
   public NoRootStaxEventItemWriter<Settlement> ZARItemWriter() throws Exception {
    NoRootStaxEventItemWriter<Settlement> ItemWriter = new NoRootStaxEventItemWriter<>();
    FileSystemResource resource = new FileSystemResource("FileZAR1.xml");
    ItemWriter.setName("ZARItemWriter");
       ItemWriter.setResource(resource);
       marshaller.setPackagesToScan("com.model");
       ItemWriter.setMarshaller(marshaller);
       ItemWriter.afterPropertiesSet();
       return ItemWriter;
   }
    @Qualifier("ZMWItemWriter")
    @Bean(destroyMethod="")
   public NoRootStaxEventItemWriter<Settlement> ZMWItemWriter() throws Exception {
    NoRootStaxEventItemWriter<Settlement> ItemWriter = new NoRootStaxEventItemWriter<>();
    FileSystemResource resource = new FileSystemResource("FileZMW1.xml");
    ItemWriter.setName("ZMWItemWriter");
    ItemWriter.setResource(resource);
    marshaller.setPackagesToScan("com.model");
    ItemWriter.setMarshaller(marshaller);
    ItemWriter.afterPropertiesSet();
      return ItemWriter;
   }

1 ответ

Решение

Пожалуйста, проверьте пример ниже и посмотрите, работает ли он для вас. Вы создаете карту писателей, чтобы каждый раз не создавать экземпляр нового писателя.

Писатель однозначно идентифицируется по (FileId, ProcessDate, Detail Currency):

String fileNameKey = item.getHeader().getFileId() + item.getHeader().getProcessDate().toString() + settlementDetail.getCurrency();

Вот код для писателя:

@Component
public class SettlementWriter implements ItemStream, ItemWriter<Settlement> {

    private final Map<String, StaxEventItemWriter<Settlement>> writers = new HashMap<>();

    private ExecutionContext executionContext;

    @Autowired
    private Marshaller marshaller;

    @Override
    public void open(ExecutionContext executionContext) throws ItemStreamException {
        this.executionContext = executionContext;
    }

    @Override
    public void update(ExecutionContext executionContext) throws ItemStreamException {
    }

    @Override
    public void close() throws ItemStreamException {
        for (StaxEventItemWriter f : writers.values()) {
            f.close();
        }
    }

    @Override
    public void write(List<? extends Settlement> items) throws Exception {
        for (Settlement item : items) {
            for (SettlementDetail det : item.getDetails()) {
                StaxEventItemWriter<Settlement> detailWriter = getFlatFileItemWriter(item, det);
                detailWriter.write(Arrays.asList(item));    
            }
        }
    }

    public StaxEventItemWriter<Settlement> getFlatFileItemWriter(Settlement item, SettlementDetail settlementDetail) {
        String fileNameKey = item.getHeader().getFileId() + item.getHeader().getFilename() + settlementDetail.getCurrency();

        StaxEventItemWriter<Settlement> itemWriter = writers.get(fileNameKey);

        if (itemWriter == null) {

            itemWriter = new StaxEventItemWriter<>();

            try {

                FileSystemResource resource = new FileSystemResource(fileNameKey+".xml");

                itemWriter.setName(fileNameKey);
                itemWriter.setResource(resource);
                marshaller.setPackagesToScan("com.model");
                itemWriter.setMarshaller(marshaller);
                itemWriter.afterPropertiesSet();

                itemWriter.open(executionContext);

            } catch (Exception e) {
                e.printStackTrace();
            }
            writers.put(fileNameKey, itemWriter);
        }
        return itemWriter;
    }
}

Надеюсь это поможет.

Другие вопросы по тегам