java.lang.ClassCastException: java.util.Date cannot be cast to java.lang.String when using Univocity

Sander_M picture Sander_M · Oct 3, 2016 · Viewed 9k times · Source

I am trying to read a java.sql.Date field and parse it to a java bean using Univocity with the following code:

public class Example {

    public static void main(final String[] args) throws FileNotFoundException {
        final BeanListProcessor<Person> rowProcessor = new BeanListProcessor<Person>(Person.class);

        final CsvParserSettings parserSettings = new CsvParserSettings();
        parserSettings.setProcessor(rowProcessor);
        parserSettings.setHeaderExtractionEnabled(false);
        parserSettings.getFormat().setDelimiter('|');       

        final String line = "0|John|12-04-1986";
        final CsvParser parser = new CsvParser(parserSettings);
        parser.parseLine(line);

        final List<Person> beans = rowProcessor.getBeans();

        for (final Person person : beans) {
            // Expected print: Birthday: 12-04-1986
            System.out.println("Birthday: " + person.getBirthDate());
        }       
    }
}

but I am getting the following exception Caused by: java.lang.ClassCastException: java.util.Date cannot be cast to java.lang.String with additional information of com.univocity.parsers.common.DataProcessingException: Error converting value 'Sat Apr 12 00:00:00 CEST 1986' using conversion com.univocity.parsers.conversions.TrimConversion when parsing the line with parser.parseLine(line);

I am trying to represent the Date to how it is in the line e.g. "12-04-1986" and I tried providing the conversion "dd-MM-yyyy", unfortunately to no avail.

What am I missing in my code to get the expected syso of "Birthday: 12-04-1986" ?

EDIT: using java.util.Date

The person class:

// using the correct Date object!
import java.util.Date;

import com.univocity.parsers.annotations.Format;
import com.univocity.parsers.annotations.Parsed;

public class Person {

    @Parsed(index=0)
    private Integer id;

    @Parsed(index=1)
    private String name;

    @Parsed(index=2)
    @Format(formats = "dd-MM-yyyy")
    private Date birthDate;

    //getters and setters ommited
}

When changing the Date object to a java.util.Date and applying the correct date format on the java.util.Date object the print is correctly displaying the expected result.

Answer

Jeronimo Backes picture Jeronimo Backes · Oct 4, 2016

The first issue is the conversion sequence you defined:

Conversions.toDate("dd-MM-yyyy"), Conversions.trim()

This generates a Date object, and then applies a String.trim() operation on top of a date instead of a String, which causes the error you just got.

If you change the order this should work:

Conversions.trim(), Conversions.toDate("dd-MM-yyyy")

However, your Person class must have its birthDate field annotated with @Parsed otherwise you'll get a null.

It should be easier to just add the @Format annotation on your birthDate field instead of applying that sequence of conversions. You can just declare your class like this:

public class Person{
    @Parsed
    String id;

    @Parsed
    String name;

    @Parsed
    @Format(formats = "dd-MM-yyyy") //notice that multiple formats are supported
    Date birthDate;
}

Finally, notice that the parser trims values by default so you don't need to use the trim conversion or the @Trim annotation unless you disable trimming in the settings.

Hope this helps.