Using Joda Time with Spring Data JPA

Joda Time is the standard de facto for managing dates in Java applications. Using it on Spring is straightforward, simply add the right dependency to your project and you can use it. But some attention is needed if you want use them for dates fields in your JPA entity class and correctly map them as date types on your database.

In the following we show the code for using joda types in a JPA entity class, given Hibernate as JPA implementation.

The code works with Spring Boot 1.2.2 and Hibernate 4.5.

Dependencies

Add the following dependencies on your pom.xml file:

<dependency>
  <groupId>joda-time</groupId>
  <artifactId>joda-time</artifactId>
</dependency>

<dependency>
  <groupId>org.jadira.usertype</groupId>
  <artifactId>usertype.core</artifactId>
  <version>3.1.0.CR1</version>
</dependency>

The first dependency provide the joda time library while the second one provides mappings for joda types to use in JPA entities.

Application.properties

Enable autoregistration of Jadira Usertypes in the application.properties file adding the following line:

src/main/resources/application.properties
spring.jpa.properties.jadira.usertype.autoRegisterUserTypes = true

Look here an example of an application.properties file using this configuration.

JPA entity’s fields

This is all you need for using Joda Time types with JPA and Hibernate!

Now you can add Joda types on your JPA entity:

// Will be mapped as DATETIME (on MySQL)
private DateTime createTime;

// Will be mapped as DATE (on MySQL), i.e. only date without timestamp
private LocalDate birthdayDate;

You can see here for an example entity using these types.

Spring controllers

In order to bind dates from Spring controllers add the jackson data bind library:

<dependency>
  <groupId>com.fasterxml.jackson.jaxrs</groupId>
  <artifactId>jackson-jaxrs-json-provider</artifactId>
  <version>2.2.1</version>
</dependency>

<dependency>
  <groupId>com.fasterxml.jackson.datatype</groupId>
  <artifactId>jackson-datatype-joda</artifactId>
</dependency>

Now you can bind JSON to Java object containing Joda dates from your controller.

For example, having this entity class:

@Entity
@Table(name = "users")
public class User {

  @Id
  @GeneratedValue(strategy = GenerationType.AUTO)
  private long id;

  // For JSON binding use the format: "1970-01-01T00:00:00.000+0000"
  private DateTime createTime;

  // For JSON binding use the format: "1970-01-01" (yyyy-MM-dd)
  private LocalDate birthdayDate;

  // Getters and setters methods
  // ...
}

It can be used a controller method like this to receiving a User object as JSON:

@RequestMapping(
    value = "/user",
    method = RequestMethod.POST,
    consumes = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public ResponseEntity<?> addUser(@RequestBody User user) {
  // Handle the User object here
  // ....
}

Sending a JSON like this:

{"birthdayDate":"2001-03-02"}

will be created a User object binding its birthday date.

The @Type annotation

If you don’t want to enable the autoRegisterUserTypes configuration in the application.properties you can manually specify the Jadira type mapping to use (see here), using the @Type annotation:

// Will be mapped as DATETIME (on MySQL)
@Type(type = "org.jadira.usertype.dateandtime.joda.PersistentDateTime")
private DateTime createTime;

// Will be mapped as DATE (on MySQL), i.e. only date without timestamp
@Type(type = "org.jadira.usertype.dateandtime.joda.PersistentLocalDate")
private LocalDate birthdayDate;