Failed to convert property value of type 'java.lang.String' to required type 'java.time.LocalDate' for property 'date' in thymeleaf form

11,488

It's an old question, but I'm leaving an answer just for future readers.
This is not an issue with thymeleaf, and more of an issue of @DateTimeFormat binding.
The example in the question above will work if the Datum class is changed like so:

Solution 1.

class Datum {
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    var date: LocalDate? = null
}

note that the date field has been moved from declaring in the primary constructor into the class body.
(notice the change from Datum (...) to Datum {...})

Solution 2.

class Datum (
   @field:DateTimeFormat(pattern = "yyyy-MM-dd") var date: LocalDate? = null
)

if you need to have it declared inside constructor due to having it as data class or other reasons, you have to annotate using use-site targets.
HOWEVER, beware that Solution 2 may not always work. I cannot reproduce in a sample project - but in a real-life project, there was an issue where @field:DateTimeFormat didn't correctly bind the request parameter string to the Date object. It sometimes worked and sometimes didn't, making it very tricky to debug.
When it didn't work, it spewed out errors like Validation failed for object='Datum'. Error count: 1, while reverting to Solution 1 instead always worked. Every time we compiled again, Solution 2 sometimes worked and randomly broke without any code changes.
We've resorted to strictly putting @DateTimeFormat annotated fields down to the class body declaration to insure it works.

Share:
11,488

Related videos on Youtube

M.T
Author by

M.T

Updated on June 04, 2022

Comments

  • M.T
    M.T almost 2 years
    <form th:action="@{/hi}"  th:object="${datum}" method="post">
        <p>date : <input type="date" th:field="*{date}"/> </p>
        <p><input type="submit" value="Submit" /> <input type="reset" value="Reset" /></p>
    </form>
    

    Controller for form above

    @PostMapping("/hi")
    fun testum(@ModelAttribute datum: Datum) {
        println(datum)
    }
    

    simple pojo class

    class Datum(
            @DateTimeFormat(pattern = "yyyy-MM-dd")
            var date: LocalDate? = null
    )
    

    I am trying to send date in form but get this exception:

    Resolved exception caused by Handler execution: org.springframework.validation.BindException: org.springframework.validation.BeanPropertyBindingResult: 1 errors
    Field error in object 'datum' on field 'date': rejected value [2018-06-20]; codes [typeMismatch.datum.date,typeMismatch.date,typeMismatch.java.time.LocalDate,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [datum.date,date]; arguments []; default message [date]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'java.time.LocalDate' for property 'date'; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [java.time.LocalDate] for value '2018-06-20'; nested exception is java.lang.IllegalArgumentException: Parse attempt failed for value [2018-06-20]]
    

    But if I change type from LocalDate to String it works fine. I want to map date that is in form to date property of Datum class. can anyone help me with that? any links? thanks.

    This link did not help me similar problem

  • M.T
    M.T almost 6 years
    it is not java 10 it is kotlin. thanks. switched back to java from kotlin
  • M.T
    M.T almost 6 years
    class Datum ( @DateTimeFormat(pattern = "yyyy-MM-dd") var date: LocalDate ) Problem was that I create properties in primary constructor, I do not know why but thymeleaf cannot set values in that way. it did not work with default values even class Datum ( @DateTimeFormat(pattern = "yyyy-MM-dd") var date: LocalDate = LocalDate.MIN )
  • Gyuhyeon Lee
    Gyuhyeon Lee over 4 years
    Unfortunately this answer is totally unrelated to the question. It doesn't use the correct language(kotlin), and all it points out is that it works in Java. The main issue in the original question is not having annotation use targets set up correctly, so this answer should probably be downvoted for less visibility to prevent future readers getting confused.
  • Anu
    Anu almost 4 years
    @Yussef You saved my day