Java LocalDate在Spring bean中不起作用

huangapple go评论120阅读模式
英文:

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&lt;SchoolOrders&gt; getOrdersInAdvance(){
JdbcCursorItemReader&lt;SchoolOrders&gt; jdbcCursorReader = new JdbcCursorItemReader();
String query = String.format(&quot;SELECT ORDER_NUMBER,STORE_NUMBER,PAYMENTINFO FROM ORDERS WHERE ORDER_DATE=%1$s&quot;,new Object[]{LocalDate.now(ZoneID.of(&quot;Asia/Kolkata&quot;)).plusDays(1)});
jdbcCursorReader .setDataSource(dataSource);
jdbcCursorReader .setSql(query);
jdbcCursorReader .setVerifyCurosrPosition(true);
jdbcCursorReader .setRowMapper(new BeanPropertyMapper&lt;SchoolOrders&gt;(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中有一个与日期/时间相关的敏感项,需要在每次执行JobStep时刷新,您可以分别使用@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&lt;SchoolOrders&gt; 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&lt;SchoolOrders&gt; getOrdersInAdvance(){
  JdbcCursorItemReader&lt;SchoolOrders&gt; jdbcCursorReader = new JdbcCursorItemReader();
  String query = String.format(&quot;SELECT ORDER_NUMBER,STORE_NUMBER,PAYMENTINFO FROM ORDERS WHERE ORDER_DATE=%1$s&quot;,new Object[]{LocalDate.now(ZoneID.of(&quot;Asia/Kolkata&quot;)).plusDays(1)});
  jdbcCursorReader .setDataSource(dataSource);
  jdbcCursorReader .setSql(query);
  jdbcCursorReader .setVerifyCurosrPosition(true);
  jdbcCursorReader .setRowMapper(new BeanPropertyMapper&lt;SchoolOrders&gt;(SchoolOrders.class));
  return jdbcCursorReader;
}

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

huangapple
  • 本文由 发表于 2020年8月31日 11:49:09
  • 转载请务必保留本文链接:https://go.coder-hub.com/63664532.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定