【发布时间】:2021-01-23 23:17:46
【问题描述】:
我编写了一个 spring 批处理作业,它读取 CSV 并写入 SQL 服务器数据库。 CSV 文件有一些类型为Date 和TimeStamp 的字段。我正在使用 FlatFileItemReader 和 JdbcBatchItemWriter。
我的 CSV 中的日期格式是 yyyy-MM-dd 时间戳格式为 yyyy-MM-dd HH:mm:ss.SSSSSS
注意:我使用的是 java.sql.Date 和 TimeStamp,而不是 java.util.Date 和 TimeStamp
用户类别:
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User{
private String firstName;
private String lastName;
private Date dateOfBirth;
private Date dateOfJoining;
private TimeStamp timeStampReg;
...
我使用相同的模型类 User 在不同的步骤中从数据库中读取。
配置类中的 Reader 如下所示:
@Configuration
public class BatchConfigClass{
//Step 1
@Bean
public FlatFileItemReader<User> itemReader() {
FlatFileItemReader<User> flatFileItemReader = new FlatFileItemReader<>();
flatFileItemReader.setResource(inputResource);
flatFileItemReader.setName("CSV-Reader");
flatFileItemReader.setLineMapper(lineMapper());
return flatFileItemReader;
}
@Bean
public LineMapper<User> lineMapper() {
DefaultLineMapper<User> defaultLineMapper = new DefaultLineMapper<>();
DelimitedLineTokenizer lineTokenizer = new DelimitedLineTokenizer();
lineTokenizer.setDelimiter(",");
lineTokenizer.setStrict(false);
lineTokenizer.setNames(new String[]{"firstName", "lastName", "dateOfBirth", "dateOfJoining","timeStampReg"});
BeanWrapperFieldSetMapper<User> fieldSetMapper = new BeanWrapperFieldSetMapper<>();
fieldSetMapper.setTargetType(User.class);
defaultLineMapper.setLineTokenizer(lineTokenizer);
defaultLineMapper.setFieldSetMapper(fieldSetMapper);
return defaultLineMapper;
}
...
在运行作业时,我收到错误:
Parsing error at line: 1 in resource=Path to the CSV file
Failed to convert property value of type 'java.lang.String' to required type 'java.sql.Date' for property 'dateOfBirth';
Field error in object 'target' on field 'dateOfBirth': rejected value [1998-12-31]; codes [typeMismatch.target.dateOfBirth,typeMismatch.dateOfBirth,typeMismatch.java.sql.Date,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [target.dateOfBirth,dateOfBirth]; arguments []; default message [dateOfBirth]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'java.sql.Date' for property 'dateOfBirth'; nested exception is java.lang.IllegalStateException: Cannot convert value of type 'java.lang.String' to required type 'java.sql.Date' for property 'dateOfBirth': no matching editors or conversion strategy found]
它对其他日期和时间戳字段(dateOfJoining 和 timeStampReg)给出相同的错误
编辑:
我通过以下解决方案解决了Date 类型字段的错误,但我仍然收到TimeStamp 类型字段的相同错误。
我创建了一个custom BeanWrapperFieldSetMapper 并覆盖了它的initBinder 以添加一个CustomDateEditor。
public class MyCustomBeanWrapperFieldSetMapper<User> extends BeanWrapperFieldSetMapper<FSMChequePayment> {
@Override
protected void initBinder(DataBinder binder) {
CustomDateEditor editor = new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"), true);
binder.registerCustomEditor(Date.class, editor);
CustomDateEditor editorTimeStamp = new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSSSS"), true);
binder.registerCustomEditor(TimeStamp.class,editorTimeStamp);
}
}
并在flatFileItemReader bean 中使用它的对象而不是实际的BeanWrapperFieldSetMapper,方法是将其替换为:
MyCustomBeanWrapperFieldSetMapper<User> fieldSetMapper = new MyCustomBeanWrapperFieldSetMapper<>();
PS:自定义编辑器不适用于 java.sql.Date 和 java.sql.TimeStamp。所以我不得不切换到java.util.Date。这解决了Date 类型的问题,但TimeStamp 类型的错误仍然存在。
【问题讨论】:
标签: java spring spring-boot type-conversion spring-batch