Spring Boot + Spring Data JPA + Java 8 date and time (JSR310)

In Spring Boot + Spring Data JPA application, to support the JSR310 java.time.* APIs, we need to register this Jsr310JpaConverters manually.


import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.data.jpa.convert.threeten.Jsr310JpaConverters;

@EntityScan(
        basePackageClasses = {Application.class, Jsr310JpaConverters.class}
)
@SpringBootApplication
public class Application {
	//...
}

P.S Tested with Spring Boot 1.5.1.RELEASE, Spring Data JPA 1.11.0.RELEASE

1. Full Example

1.1 A model contains a java.time.LocalDate field.


package com.mkyong.model;

import javax.persistence.*;
import java.time.LocalDate;

@Entity
public class Customer {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "CUST_SEQ")
    @SequenceGenerator(sequenceName = "customer_seq", allocationSize = 1, name = "CUST_SEQ")
    Long id;

    String name;

    @Column(name = "CREATED_DATE")
    LocalDate date;
	
	//...

1.2 @EntityScan to scan and register Jsr310JpaConverters like this :


package com.mkyong;

import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.data.jpa.convert.threeten.Jsr310JpaConverters;

import java.util.Arrays;

//for jsr310 java 8 java.time.*
@EntityScan(
        basePackageClasses = {Application.class, Jsr310JpaConverters.class}
)
@SpringBootApplication
public class Application {

    public static void main(String[] args) throws Exception {
        SpringApplication.run(Application.class, args);
    }

    @Bean
    public CommandLineRunner run(ApplicationContext appContext) {
        return args -> {

            System.out.println("hello World!");
            
        };
    }

}

References

  1. Jsr310JpaConverters JavaDoc
  2. JSR 310: Date and Time API
  3. Spring Data MongoDB + JSR-310 or Java 8 new Date APIs

5 comments on “Spring Boot + Spring Data JPA + Java 8 date and time (JSR310)

  1. hi sir its nice, you r giving your knowledge for free thank you for that but i need some exaples on jsf its hard to find jsf work online explained like you.

    Reply
  2. This did not work for me. I still get error: java.sql.SQLException: Bad format for DATE ’10/13/2015 12:00:00 AM’ in column 2.

    import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
    import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
    import org.springframework.boot.builder.SpringApplicationBuilder;
    import org.springframework.boot.web.support.SpringBootServletInitializer;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.context.annotation.PropertySource;
    import org.springframework.data.jpa.convert.threeten.Jsr310JpaConverters;

    @EntityScan(
    basePackageClasses = {MehApplication.class, Jsr310JpaConverters.class}
    )
    @SpringBootApplication
    @PropertySource( {
    “classpath:/meh_application.properties”
    })
    @EnableAutoConfiguration(exclude = { DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class })
    @ComponentScan( { “com.spins.productlibrary.environment”, “com.spins.productlibrary.service”, “com.spins.productlibrary.model” })
    public class MehApplication extends SpringBootServletInitializer {

    public static void main(String[] args) {
    TimeZone.setDefault(TimeZone.getTimeZone(“Etc/UTC”));
    ApplicationContext ac = SpringApplication.run(MehApplication.class, args);
    Logger logr = LoggerFactory.getLogger(MehApplication.class);
    logr.debug(“Beans provided by Spring Boot:”);
    String[] beanNames = ac.getBeanDefinitionNames();
    Arrays.sort(beanNames);
    for (String beanName : beanNames) {
    logr.debug(“Bean provided by Spring Boot:” + beanName);
    }
    }

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
    return application;
    }

    @Override
    public void onStartup(ServletContext servletContext) throws
    ServletException {
    super.onStartup(servletContext);
    }
    }

    package com.spins.productlibrary.model.cloud.metadata;

    import java.time.LocalDate;
    import java.time.format.DateTimeFormatter;
    import java.util.Date;
    import javax.persistence.Column;
    import javax.persistence.Entity;
    import javax.persistence.Id;
    import javax.persistence.Table;

    @Entity
    @Table(name = “iri_20_week_threshold”)
    public class Iri20WeekThreshold {
    @Id
    @Column(name = “iri_20_week_threshold_id”, unique = true, nullable = false)
    private int threshoId;

    @Column(name = “start_date”)
    private LocalDate startDate;

    @Column(name = “end_date”)
    private LocalDate endDate;

    @Column(name = “start_date_fixed”)
    private Date startDateFixed;

    @Column(name = “end_date_fixed”)
    private Date endDateFixed;

    private static final DateTimeFormatter dateFormat = DateTimeFormatter.ofPattern(“M/d/yyyy hh:mm:ss a”);

    public int getThreshoId() {
    return threshoId;
    }

    public void setThreshoId(int threshoId) {
    this.threshoId = threshoId;
    }

    public LocalDate getStartDate() {
    return this.startDate;
    }

    public void setStartDate(LocalDate startDate) {
    this.startDate = startDate;
    }

    public LocalDate getEndDate() {
    return this.endDate;
    }

    public void setEndDate(LocalDate endDate) {
    this.endDate = endDate;
    }

    public Date getStartDateFixed() {
    return startDateFixed;
    }

    public void setStartDateFixed(Date startDateFixed) {
    this.startDateFixed = startDateFixed;
    }

    public Date getEndDateFixed() {
    return endDateFixed;
    }

    public void setEndDateFixed(Date endDateFixed) {
    this.endDateFixed = endDateFixed;
    }

    // private LocalDate convert(String date) {
    // return LocalDate.parse(date, dateFormat);
    // }
    }

    Reply
  3. I think it’s way better to just change name of ‘LocalDate date’ to ‘LocalDate createdDate’ and Spring Boot will create column in database named ‘created_date’ 🙂

    Reply

Leave a Comment

Your email address will not be published. Required fields are marked *