Jayendran Gurumoorthy
Jayendran Gurumoorthy

Reputation: 25

Java LocalDate is not working within Spring bean

I am working in a Spring Batch project. I have bean that reads data from SQL Server DB. With in the read query, I am setting date to extract information from table. The problem is I am using String.format() method to set query date parameters using LocalDate. I have to add one day with current date. The bean is being initialized without any issues and on first run the query is run as per requirement but during consecutive run the LocalDate is generating only current date without adding 1 day.

@Bean
public JdbcCursorItemReader<SchoolOrders> getOrdersInAdvance(){
JdbcCursorItemReader<SchoolOrders> jdbcCursorReader = new JdbcCursorItemReader();
String query = String.format("SELECT ORDER_NUMBER,STORE_NUMBER,PAYMENTINFO FROM ORDERS WHERE ORDER_DATE=%1$s",new Object[]{LocalDate.now(ZoneID.of("Asia/Kolkata")).plusDays(1)});
jdbcCursorReader .setDataSource(dataSource);
jdbcCursorReader .setSql(query);
jdbcCursorReader .setVerifyCurosrPosition(true);
jdbcCursorReader .setRowMapper(new BeanPropertyMapper<SchoolOrders>(SchoolOrders.class));
returns jdbcCursorReader;
}

I know LocalDate is immutable but the date is not persisted within object level and generated instantly.

Can someone please help me in resolving this issue! Thanks in Advance.

Upvotes: 0

Views: 646

Answers (1)

Philip Wrage
Philip Wrage

Reputation: 1569

Using @Bean to specify the JdbcCursorItemReader<SchoolOrders> results in a singleton-scoped bean (default). The method getOrdersInAdvance() is therefore only run in its entirety once in order to configure the Spring Bean, and all subsequent calls will simply return the cached bean unless - as you have observed - the application is restarted.

If you have a date/time sensitive item within the Spring Bean that needs to be refreshed each time the Job or Step is executed, you can annotate that bean method with @JobScope or @StepScope, respectively.

From what I can understand in your case, I would suggest you first try to configure your JdbcCursorItemReader as job-scoped.

@Bean
@JobScope
public JdbcCursorItemReader<SchoolOrders> getOrdersInAdvance(){
  JdbcCursorItemReader<SchoolOrders> jdbcCursorReader = new JdbcCursorItemReader();
  String query = String.format("SELECT ORDER_NUMBER,STORE_NUMBER,PAYMENTINFO FROM ORDERS WHERE ORDER_DATE=%1$s",new Object[]{LocalDate.now(ZoneID.of("Asia/Kolkata")).plusDays(1)});
  jdbcCursorReader .setDataSource(dataSource);
  jdbcCursorReader .setSql(query);
  jdbcCursorReader .setVerifyCurosrPosition(true);
  jdbcCursorReader .setRowMapper(new BeanPropertyMapper<SchoolOrders>(SchoolOrders.class));
  return jdbcCursorReader;
}

I would also suggest you read the Spring Batch documentation for late binding of job and step attributes.

Upvotes: 2

Related Questions