【发布时间】:2022-01-24 12:05:27
【问题描述】:
我正在尝试使用 CSV 文件中的值填充 H2 数据库,如下所示:
@Component
public class DBWriterOrder implements ItemWriter<OrderEntity> {
private OrderRepository orderRepository;
@Autowired
public DBWriterOrder(OrderRepository orderRepository) {
this.orderRepository = orderRepository;
}
@Override
public void write(List<? extends OrderEntity> orders) throws Exception {
System.out.println("Data Saved for Orders: " + orders);
orderRepository.saveAll(orders);
}
}
@Component
public class ProcessorOrder implements ItemProcessor<OrderEntity, OrderEntity> {
public SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");
@Override
public OrderEntity process(OrderEntity orderEntity) throws Exception {
Date deliveryDate = sdf.parse(orderEntity.getDeliveryDate().toString());
long deliveryDateInMillis = deliveryDate.getTime();
orderEntity.setDeliveryDate(deliveryDateInMillis);
Date lastUpdated = sdf.parse(orderEntity.getLastUpdated().toString());
long lastUpdatedInMillis = lastUpdated.getTime();
orderEntity.setLastUpdated(lastUpdatedInMillis);
return orderEntity;
}
}
@Configuration
@EnableBatchProcessing
public class SpringBatchConfigOrder {
@Bean
public Job jobOrder(JobBuilderFactory jobBuilderFactory,
StepBuilderFactory stepBuilderFactory,
ItemReader<OrderEntity> itemReader,
ItemProcessor<OrderEntity, OrderEntity> itemProcessor,
ItemWriter<OrderEntity> itemWriter
) {
Step step = stepBuilderFactory.get("ETL-file-load")
.<OrderEntity, OrderEntity>chunk(100)
.reader(itemReader)
.processor(itemProcessor)
.writer(itemWriter)
.build();
return jobBuilderFactory.get("ETL-Load")
.incrementer(new RunIdIncrementer())
.start(step)
.build();
}
@Bean
public FlatFileItemReader<OrderEntity> itemReaderOrder() {
FlatFileItemReader<OrderEntity> flatFileItemReader = new FlatFileItemReader<>();
flatFileItemReader.setResource(new FileSystemResource("src/main/resources/orders.csv"));
flatFileItemReader.setName("CSV-Reader");
flatFileItemReader.setLinesToSkip(1);
flatFileItemReader.setLineMapper(lineMapperOrder());
return flatFileItemReader;
}
@Bean
public LineMapper<OrderEntity> lineMapperOrder() {
DefaultLineMapper<OrderEntity> defaultLineMapper = new DefaultLineMapper<>();
DelimitedLineTokenizer lineTokenizer = new DelimitedLineTokenizer();
lineTokenizer.setDelimiter(",");
lineTokenizer.setStrict(false);
lineTokenizer.setNames("id","destination","deliveryDate","statusOrder","lastUpdated");
BeanWrapperFieldSetMapper<OrderEntity> fieldSetMapper = new BeanWrapperFieldSetMapper<>();
fieldSetMapper.setTargetType(OrderEntity.class);
defaultLineMapper.setLineTokenizer(lineTokenizer);
defaultLineMapper.setFieldSetMapper(fieldSetMapper);
return defaultLineMapper;
}
}
@RestController
@RequestMapping("/loadOrder")
public class OrderLoadController {
@Autowired
JobLauncher jobLauncherOrder;
@Autowired
Job jobOrder;
@GetMapping
public BatchStatus load() throws JobParametersInvalidException, JobExecutionAlreadyRunningException, JobRestartException, JobInstanceAlreadyCompleteException {
Map<String, JobParameter> maps = new HashMap<>();
maps.put("time", new JobParameter(System.currentTimeMillis()));
JobParameters parameters = new JobParameters(maps);
JobExecution jobExecution = jobLauncherOrder.run(jobOrder, parameters);
System.out.println("JobExecution: " + jobExecution.getStatus());
System.out.println("Batch is Running...");
while (jobExecution.isRunning()) {
System.out.println("...");
}
return jobExecution.getStatus();
}
}
这也是我的实体类:
@Entity(name = "orders")
@Data
public class OrderEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToOne(fetch = FetchType.EAGER)
private DestinationEntity destination;
private Long deliveryDate;
@Enumerated(value = EnumType.STRING)
private OrderStatus statusOrder;
private Long lastUpdated;
}
这是我的 CSV 文件:
id,destination,deliveryDate,statusOrder,lastUpdated
1,Ploiesti,15-12-2021,NEW,15-12-2021
2,Ploiesti,15-12-2021,NEW,15-12-2021
3,Pitesti,15-12-2021,NEW,15-12-2021
4,Pitesti,15-12-2021,NEW,15-12-2021
5,Pitesti,15-12-2021,NEW,15-12-2021
当我调用端点 localhost:8082/loadController 时,我的数据库没有被填充,它仍然是空的,我得到的只是控制台中的这个错误:
org.springframework.batch.item.file.FlatFileParseException: Parsing error at line: 2 in resource=[file [C:\Users\ALEX\Desktop\FinalProject\demo\src\main\resources\orders.csv]], input=[1,Ploiesti,15-12-2021,NEW,15-12-2021]
at org.springframework.batch.item.file.FlatFileItemReader.doRead(FlatFileItemReader.java:189) ~[spring-batch-infrastructure-4.3.4.jar:4.3.4]
Caused by: org.springframework.validation.BindException:
org.springframework.validation.BeanPropertyBindingResult: 3 errors
Field error in object 'target' on field 'lastUpdated': rejected value [15-12-2021]; codes [typeMismatch.target.lastUpdated,typeMismatch.lastUpdated,typeMismatch.java.lang.Long,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [target.lastUpdated,lastUpdated]; arguments []; default message [lastUpdated]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'java.lang.Long' for property 'lastUpdated'; nested exception is java.lang.NumberFormatException: For input string: "15-12-2021"]
Field error in object 'target' on field 'destination': rejected value [Ploiesti]; codes [typeMismatch.target.destination,typeMismatch.destination,typeMismatch.com.example.demo.destination.DestinationEntity,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [target.destination,destination]; arguments []; default message [destination]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'com.example.demo.destination.DestinationEntity' for property 'destination'; nested exception is java.lang.IllegalStateException: Cannot convert value of type 'java.lang.String' to required type 'com.example.demo.destination.DestinationEntity' for property 'destination': no matching editors or conversion strategy found]
Field error in object 'target' on field 'deliveryDate': rejected value [15-12-2021]; codes [typeMismatch.target.deliveryDate,typeMismatch.deliveryDate,typeMismatch.java.lang.Long,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [target.deliveryDate,deliveryDate]; arguments []; default message [deliveryDate]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'java.lang.Long' for property 'deliveryDate'; nested exception is java.lang.NumberFormatException: For input string: "15-12-2021"]
最后,我的问题是我应该怎么做,我应该怎么做才能把事情做好? 我更喜欢完整的代码解决方案,因为我不够先进,无法自己解决这个问题,只能通过指示来解决。
【问题讨论】:
-
从实际阅读错误信息开始。您正在尝试将字符串写入不是字符串的字段
-
@Stultuske 我了解错误消息及其出现的原因,但我不知道我应该怎么做才能使程序正常工作
-
您希望如何将字符串 'Ploiesti' 转换为 DestinationEntity 的实例 - 该代码在哪里,因为这没有发生并导致您出现此异常。
-
而且 '15-12-2021' 不是
Long -
@Chris 我确实有将这些日期转换为长值的代码,但仍然是错误
标签: java spring-boot csv jpa h2