Thursday, February 23, 2012

JacksonJsonProvider, java.util.Date and java.sql.Date

Today I had a wonderful problem related to the different date objects in Java. I had made the mistake using rs.getDate() to get a date from the database, not realizing that I lose the time part in doing so. It however became apparent to me in an unusual way:

The problem I had was that an object like this
public MyObj {
  java.util.Date myDate; 
}
was serialized by Jackson to a date string "2012-01-05", without the time.

Everywhere I read it said that java.util.Date in Jackson is serialized using unix timestamp, so I did not understand from where this formatted string came. I dug a bit in the serialization process in Jackson and I saw that it was using a SqlDateSerializer to serialize the Date, which I found strange.

I then realized that when fetching the date from the database, I iterated through a ResultSet and set myDate using
myObj.setMyDate(rs.getDate("MY_DATE"));
, which of course is a big no-no. Not only do I lose the time part, but as java.sql.Date inherits from java.util.Date (thanks, jdbc designers) I get a creepy java.sql.Date object in myObj. This in turn caused Jackson to use the SqlDateSerializer, which serialize the dates as strings without time, which I am now happy for, as it made finding out what was wrong a little easier.

So the solution became quite simple; I instead used a method which null-checked rs.getTimestamp() and created my own real java.util.Date-object using
new java.util.Date(timestamp).

2 comments:

  1. Hi Andreas, I spent around 3h with this exactly same issue. In fact, I didn't know that java.sql.Date extends reim java.util.Date. For Jackson users like us this is so tricky. Anyway, this was funny :P. Cheers

    ReplyDelete
  2. I have the same problem but, Hibernate-JPA does the mapper :(, there is another solution?

    ReplyDelete