Spring jdbctemplate exception java.time.LocalDateTime cannot be cast to java.util.Date

Viewed 728

I have a datetime type column in mysql db and file fetching column using jdbctemplate and type casting it to java.util.Date throws error. Here is my code :

I have defined the following SimpleDateFormat

private static final SimpleDateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

and use it like this

String query = "select start_time as starttime from job_tbl";

List<Map<String, Object>> myList = jdbcTemplate.queryForList(query);

for (Map<String, Object> map: myList) {
    String dateTime = dateformat.format((java.util.Date) map.get("starttime");
}

The code throws this error:

java.lang.ClassCastException:
java.time.LocalDateTime cannot be cast to java.util.Date

The same functionality was working fine in my old other projects with jdbcTemplate easily type casted to java.util.Date but in this new project, it returns date of format java.time.LocalDateTime, is there any issue with mysql-connector or any other issue??

3 Answers

java.time

The java.util Date-Time API and their formatting API, SimpleDateFormat are outdated and error-prone. It is recommended to stop using them completely and switch to the modern Date-Time API*.

From the error, it is clear that you need to cast map.get("starttime") to java.time.LocalDateTime instead of java.util.Date.

DateTimeFormatter dft = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss", Locale.ENGLISH);
String dateTime = dft.format((java.time.LocalDateTime) map.get("starttime"));   

Learn more about the modern Date-Time API* from Trail: Date Time.


* For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. 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.

For those arriving at this post after upgrading Spring Boot: The Connector/J switched to java.time classes with version 8.0.23. If you really need to keep working with util classes, override the version

    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.22</version>
    </dependency>

But, as others have said, the clean solution is to upgrade your code to the new java.time package.

Why do you need to cast it to Date. As per the logic you just need the string from the datatime.

Format LocalDateTime to String

// Get current date time
LocalDateTime currentDateTime = LocalDateTime.now();
 
// Inbuilt format
static DateTimeFormatter formatter = DateTimeFormatter.ISO_DATE_TIME;
 
// Custom format
//DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
 
// Format LocalDateTime
String formattedDateTime = currentDateTime.format(formatter);
 
//Verify
System.out.println("Formatted LocalDateTime : " + formattedDateTime);       
 
//Output:
 
//Formatted LocalDateTime : 2018-07-14T17:45:55.9483536

more details can be found here: How to parse/format dates with LocalDateTime? (Java 8)

Related