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!");
};
}
}
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’ 🙂
Spring Data JPA save(Iterable ….) exampl
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.
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);
// }
}
very helpful