英文:
Java LocalDate is not working within Spring bean
问题
我在一个Spring Batch项目中工作。我有一个bean从SQL Server数据库中读取数据。在读取查询内,我正在设置日期以从表中提取信息。问题是我正在使用String.format()
方法使用LocalDate
设置查询日期参数。我必须在当前日期上增加一天。该bean被初始化而没有任何问题,并且在第一次运行时,查询按照要求运行,但在连续运行期间,LocalDate
只生成当前日期,而没有添加1天。
@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.setVerifyCursorPosition(true);
jdbcCursorReader.setRowMapper(new BeanPropertyRowMapper<>(SchoolOrders.class));
return jdbcCursorReader;
}
我知道LocalDate
是不可变的,但日期在对象级别上没有持续,并立即生成。
有人能帮助我解决这个问题吗?提前谢谢!
英文:
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.
答案1
得分: 2
使用@Bean
来指定JdbcCursorItemReader<SchoolOrders>
会导致一个单例作用域的Bean(默认)。因此,方法getOrdersInAdvance()
只会在配置Spring Bean时完整运行一次,并且所有后续调用将简单地返回缓存的Bean,除非 - 如您所观察到的 - 应用程序被重新启动。
如果在Spring Bean中有一个与日期/时间相关的敏感项,需要在每次执行Job
或Step
时刷新,您可以分别使用@JobScope
或@StepScope
对该Bean方法进行注释。
根据我对您情况的理解,我建议您首先尝试将您的JdbcCursorItemReader
配置为作业范围。
@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;
}
我还建议您阅读Spring Batch文档中有关作业和步骤属性的延迟绑定。
英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论