Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use JodaTime with Spring and Hibernate?

So I'm encountering a problem in my Spring app. The user can enter dates using a date picker tool and these are stored in a Mysql database using Hibernate. The table uses a Date field to store them so it's not saving times. The problem is that the server is set to GMT and our users are EST or GMT-5. So the date gets correctly stored in the database, but then when it's displayed on the front end it always shows the previous date. Annoys me since I'm not saving the time but obviously it's still affecting things. Anyway, so 12/10/2001 would show up on the front end as 12/09/2011. I've looked into it and I'm not permitted to change the server to EST so I'm now looking into solving this with Jodatime (unless someone has an idea that I'm doing something else to cause this) or an easier solution.

My problem is that I can't find any good info on how to use Jodatime with Spring. Currently I'm just trying to change one object over from using java's Date to using joda's LocalDate. No matter what I try though I'm getting errors on "invalid stream header" and "could not deserialize" when it tries to pull the date object from the database and shove it into the LocalDate object.

Could someone provide me with some guidance on what I need to do for both storing and retrieving so that this works?

I'm using Spring 3.1 with annotations and all that good stuff. I'm happy to provide code but since I'm not sure what do to I don't really have any code that I think would be helpful. I could really use some help on the whole thing from the JSPs to the Database and back. I think the main thing I'm not sure of is how to store this on the server and I think that's why I'm getting Hibernate errors. The database is using Date as I mentioned, so not storing time. How do I convert a LocalDate into this?

Here is some code if it helps:

Domain Object

@Entity
public class Provision {
    @Id @GeneratedValue
    private Long id;

    private LocalDate startDate;

    //Getters and setters
}

I have a DatePropertyEditor for converting from text to Date between JSP and Spring:

public class DatePropertyEditor extends PropertyEditorSupport {
@Override
public void setAsText(String value) {
    try {
        setValue(new SimpleDateFormat("yyyy-MM-dd").parse(value));
    } catch (ParseException e) {
        setValue(null);
    }
}

@Override
public String getAsText() {
    if(getValue() != null)
        return new SimpleDateFormat("yyyy-MM-dd").format((Date) getValue());
    else
        return null;
}

}

And here is some of the JSP where data is entered:

<td align="right">Start Date:</td>
     <td><sf:input path="startDate" dojoType="dijit.form.DateTextBox" required="true" hasDownArrow="true" 
        onChange="dijit.byId('endDate').constraints.min = arguments[0];" constraints="{datePattern:'MMM d, y'}" />
</td>

None of the rest of the code deals with or touches the Date objects, all the rest is handled through annotations and injection and what not.

like image 236
cardician Avatar asked Dec 15 '11 14:12

cardician


2 Answers

I'd suggest you use the Spring 3 Converter SPI instead of regular PropertyEditors.

Then just write a custom converter:

final class StringToDateTime implements Converter<String, DateTime> {
    private static final DateTimeFormatter FORMAT = // init here

    public DateTime convert(String source) {
        return FORMAT.parseDateTime(source);
    }

}

But that's only the Spring side. You still have to make sure Hibernate knows about JodaTime. Have a look at the Joda Time - Hibernate support project for that.

like image 195
Sean Patrick Floyd Avatar answered Nov 14 '22 15:11

Sean Patrick Floyd


This problem is not new, take a look at the discussion of it that I put on my blog: http://blog.jadira.co.uk/blog/2010/5/1/javasqldate-types-and-the-offsetting-problem.html

My project (Usertype - http://usertype.sourceforge.net/) solved this with its PersistentDateTime class. I would suggest you use this to provide a usertype for your entity.

The Javadoc on this class describes how you can further tweak the zone that is used for persisting and subsequently re-inflation: http://usertype.sourceforge.net/apidocs/org/jadira/usertype/dateandtime/joda/PersistentDateTime.html

If you use Hibernate 4 you can also make use of autoregistration. For details on how to use this feature, see http://blog.jadira.co.uk/blog/2012/1/19/release-jadira-usertype-300cr1-with-support-for-joda-money-0.html

HTH

Chris

like image 39
Chris Pheby Avatar answered Nov 14 '22 15:11

Chris Pheby