Search code examples
javaspringspring-bootspring-batchtimestamp-with-timezone

typeMismatch.target spring boot batch rejected value [2020-09-18T00:00:00+02:00]


I am trying to integrate data from CSV file with spring boot using a batch, I have a problem with the date field because it is constantly rejected regardless of the type used, here is my code:

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String service;
    private Timestamp time;

    @Override
    public IndProd process(final IndProd indProd) throws Exception {
        String service = indProd.getService();
        Timestamp time = indProd.getTime();
        Long nbAppels = indProd.getNbAppels();
        Integer tempsDeReponseMoyenMillisecondes = indProd.getTempsDeReponseMoyenMillisecondes();
        Long volume = indProd.getVolume();
        BigDecimal tempsDeReponseMoyenSecondes = indProd.getTempsDeReponseMoyenSecondes();
        IndProd transformedIndProd = new IndProd(service,time,nbAppels,tempsDeReponseMoyenMillisecondes,volume,tempsDeReponseMoyenSecondes);

        return transformedIndProd;
    }

here is the error returned:

Caused by: org.springframework.validation.BindException: org.springframework.validation.BeanPropertyBindingResult: 1 errors Field error in object 'target' on field 'time': rejected value [2020-09-18T00:00:00+02:00]; codes [typeMismatch.target.time,typeMismatch.time,typeMismatch.java.sql.Timestamp,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [target.time,time]; arguments []; default message [time]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'java.sql.Timestamp' for property 'time'; nested exception is java.lang.IllegalStateException: Cannot convert value of type 'java.lang.String' to required type 'java.sql.Timestamp' for property 'time': no matching editors or conversion strategy found] at org.springframework.batch.item.file.mapping.BeanWrapperFieldSetMapper.mapFieldSet(BeanWrapperFieldSetMapper.java:201) ~[spring-batch-infrastructure-4.2.4.RELEASE.jar:4.2.4.RELEASE] at org.springframework.batch.item.file.mapping.DefaultLineMapper.mapLine(DefaultLineMapper.java:43) ~[spring-batch-infrastructure-4.2.4.RELEASE.jar:4.2.4.RELEASE] at org.springframework.batch.item.file.FlatFileItemReader.doRead(FlatFileItemReader.java:185) ~[spring-batch-infrastructure-4.2.4.RELEASE.jar:4.2.4.RELEASE] ... 56 common frames omitted

Thanks for your help


Solution

  • From the error, it clear that indProd.getTime() returns a String value which you are trying to assign to a Timestamp variable. Assuming indProd.getTime() returns a date-time string in the format, yyyy-MM-dd'T'HH:mm:ssXXX e.g. 2020-09-18T00:00:00+02:00 (as mentioned in the title of your question), you should replace

    Timestamp time = indProd.getTime();
    

    with

    Timestamp time = new Timestamp(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX").parse(indProd.getTime()).getTime());
    

    Note: java.sql.Timestamp extends java.util.Date and the date-time API of java.util and their formatting API, SimpleDateFormat are outdated and error-prone. I suggest you should stop using them completely and switch to the modern date-time API.

    Using the modern date-time API:

    OffsetDateTime odt = OffsetDateTime.parse(indProd.getTime());
    //...
    IndProd transformedIndProd = new IndProd(service,odt,nbAppels,tempsDeReponseMoyenMillisecondes,volume,tempsDeReponseMoyenSecondes);
    

    and declare the instance members as

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String service;
    private OffsetDateTime odt;// Change the type to OffsetDateTime
    

    Learn more about the modern date-time API at Trail: Date Time. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.