Issue
I have BatchConfiguration , OrderProcesser and OrderReader Class file. When I am calling Spring Boot rest service, I get a NullPointerException
.
But, when I run the SpringBoot application in Postman, it is displaying appropriate results. Also, I would like to know which step make it run multiple times , so that billerOrderId gets executed multiple times. I used https://spring.io/guides/gs/batch-processing/ to write my code .
Here is my osm-billers.csv
BillerOrderId
1233
2344
4566
@Configuration
@EnableBatchProcessing
public class BatchConfiguration {
@Autowired
public JobBuilderFactory jobBuilderFactory;
@Autowired
public StepBuilderFactory stepBuilderFactory;
@Autowired
private CsvFileToDatabaseJobConfig csvFileToDatabaseJobConfig;
@Autowired
private DatabaseToCsvFileJobConfig databaseToCsvFileJobConfig;
RestTemplate restTemplate;
@Bean
public FlatFileItemReader<Biller> reader(){
try {
FlatFileItemReader<Biller> itemReader = csvFileToDatabaseJobConfig.csvFileItemReader();
return itemReader ;
} catch (UnexpectedInputException e) {
throw new OrderBatchException("Invalid Input..." + e.getMessage());
} catch (ParseException e) {
throw new OrderBatchException("Parsing error..." + e.getMessage());
} catch (NonTransientResourceException e) {
throw new OrderBatchException("NonTransientReasource error..." + e.getMessage());
} catch (Exception e) {
throw new OrderBatchException("Unknown Read error..." + e.getMessage());
}
}
@Bean
public OrderProcessor processor() {
return new OrderProcessor();
}
@Bean
public ItemWriter<Biller> writer() {
try {
ItemWriter<Biller> itemWriter = databaseToCsvFileJobConfig.databaseCsvItemWriter();
return itemWriter;
} catch (Exception e) {
throw new OrderBatchException("Unknown Write error..." + e.getMessage());
}
}
@Bean
public Job importJobOrder(JobCompletionNotificationListner listener, Step step1) {
return jobBuilderFactory.get("importJobOrder")
.incrementer(new RunIdIncrementer())
.listener(listener)
.flow(step1)
.end()
.build();
}
@Bean
public Step step1(ItemWriter<Biller> writer) {
return stepBuilderFactory.get("step1")
.<Biller, Biller> chunk(10)
.reader((ItemReader<? extends Biller>) reader())
.processor(processor())
.writer(writer)
.build();
}
}
package com.spectrum.sci.processor;
import java.util.List;
import org.springframework.batch.item.ItemProcessor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.client.RestTemplate;
import com.spectrum.sci.model.Biller;
import com.spectrum.tos.model.Order;
import com.spectrum.tos.model.OrderRequest;
import com.spectrum.tos.model.OrderResponse;
public class OrderProcessor implements ItemProcessor<Biller, Biller>{
@Value("${osm.service.url}")
private String orderUrl;
@Value("${osm.service.username}")
private String userName;
@Value("${osm.service.password}")
private String password;
RestTemplate restTemplate;
@Override
public Biller process(Biller biller) throws Exception {
OrderRequest orderRequest = new OrderRequest();
Order order = new Order();
order.setBillerOrderId(biller.getBillerOrderId());
orderRequest.setOrder(order);
OrderReader osmReader = new OrderReader(orderUrl, userName, password, restTemplate, orderRequest);
OrderResponse orderResponse = osmReader.read();
if (orderResponse.getResult().equals("SUCCESS") ) {
return null;
} else {
//Failed transactions
return biller;
}
}
}
public class OrderReader implements ItemReader<OrderResponse>{
private static final Logger log = LoggerFactory.getLogger(OrderReader.class);
private final String apiUrl;
private final RestTemplate restTemplate;
private int nextOrderIndex;
private OrderResponse orderResponse;
@Autowired
private OrderRequest orderRequest;
private String userName;
private String password;
public OrderReader(String apiUrl, String userName, String password, RestTemplate restTemplate, OrderRequest orderRequest) {
this.apiUrl = apiUrl;
this.restTemplate = restTemplate;
this.orderRequest = orderRequest;
this.userName = userName;
this.password = password;
nextOrderIndex = 0;
}
private boolean orderisNotInitialized() {
return this.orderResponse == null;
}
private OrderResponse fetchOrderDataFromApi(OrderRequest orderRequest) {
// log.info("OrderRequest = " + orderRequest.getOrder().getBillerOrderId());
log.info("apiUrl = " + apiUrl);
log.info("userName = " + userName);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
headers.setBasicAuth(userName, password);
HttpEntity<OrderRequest> requestEntity =
new HttpEntity<OrderRequest>(orderRequest, headers);
ResponseEntity<OrderResponse> response =
restTemplate.exchange(apiUrl,HttpMethod.POST, requestEntity,OrderResponse.class);
log.info("response = " + response);
//ResponseEntity<OrderResponse[]> response = restTemplate.postForEntity(apiUrl, orderRequest, OrderResponse[].class);
OrderResponse orderResponse = response.getBody();
//return Arrays.asList(orderResponse);
return orderResponse;
}
@Override
public OrderResponse read()
throws Exception, UnexpectedInputException, ParseException, NonTransientResourceException {
if (orderisNotInitialized()) {
orderResponse = fetchOrderDataFromApi(orderRequest);
}
/*
OrderResponse nextOrder = null;
if (nextOrderIndex < orderResponse.size()) {
nextOrder = orderResponse.get(nextOrderIndex);
nextOrderIndex++;
}
return nextOrder; */
return orderResponse;
}
}
Here is the error.
main] o.s.batch.core.step.AbstractStep : Encountered an error executing step step1 in job importJobOrder
java.lang.NullPointerException: null
at com.spectrum.sci.processor.OrderReader.fetchOrderDataFromApi(OrderReader.java:70) ~[classes/:na]
at com.spectrum.sci.processor.OrderReader.read(OrderReader.java:84) ~[classes/:na]
at com.spectrum.sci.processor.OrderProcessor.process(OrderProcessor.java:34) ~[classes/:na]
at com.spectrum.sci.processor.OrderProcessor.process(OrderProcessor.java:1) ~[classes/:na]
Solution
your restTemplate is null, you never initialize it.
try with restTemplate = new RestTemplate();
in your OrderProcessor
Answered By - sap
Answer Checked By - Marilyn (JavaFixing Volunteer)