Search code examples
javastringcsvlocaldateunivocity

Why univocity's CsvParser throwing error when use LocalDate as the datatype for POJO and How to reslove it?


I am using Univocity's CSVParser to read csv file. My POJO look something like this.

import java.time.LocalDate;
import com.univocity.parsers.annotations.NullString;
import com.univocity.parsers.annotations.Parsed;
import lombok.Builder;
import lombok.Getter;

@Getter
@Setter
public class TempClass {

    @Parsed(field = "A")
    private int a;

    @Parsed(field = "B")
    private String b;

    @Parsed(field = "C")
    private LocalDate c;
}

My csv file look something like this:-

A,B,C
1,"Hi","2019-01-12"
2,"Hey","2019-01-13"
3,"Hello","2019-01-14"

Now when I try to read this file using CsvParser, it throws error saying Unable to set value '2019-01-12' of type 'java.lang.String' to field attribute 'c'.

Here I am guessing it is throwing error because it can not implicitly convert String to LocalDate. If that is the case then How can it able to convert String to int?

Is there way to solve the error Unable to set value '2019-01-12' of type 'java.lang.String' to field attribute 'c'?(without changeing data type of TempClass.c)


Solution

  • Univocity-parsers is still built on Java 6. LocalDate is not directly supported out of the box, but can to provide a conversion yourself. Something like:

    public class LocalDateFormatter implements  Conversion<String, LocalDate> {
    
        private DateTimeFormatter formatter;
    
        public LocalDateFormatter(String... args) {
            String pattern = "dd MM yyyy";
            if(args.length > 0){
                pattern = args[0];
            }
            this.formatter = DateTimeFormatter.ofPattern(pattern);
        }
    
        @Override
        public LocalDate execute(String input) {
            return LocalDate.parse(input, formatter);
        }
    
        @Override
        public String revert(LocalDate input) {
            return formatter.format(input);
        }
    }
    

    Then annotate your fields with @Convert and provide your conversion class:"

    @Parsed(field = "C")
    @Convert(conversionClass = LocalDateFormatter.class, args = "yyyy-MM-dd")
    private LocalDate c;
    

    The next version (3.0.0) is coming soon with support for this and a lot more.

    Hope this helps.