허원철의 개발 블로그

Spring Boot + JPA + Time package Issue 본문

web

Spring Boot + JPA + Time package Issue

허원철 2017. 3. 22. 10:04

이번 글은 Spring Boot + Data JPA를 사용하면서 Java 8에서 나온 Time package 추가 했을 때에 대한 이슈 글입니다.

 

 

스펙 정리

 

1
2
3
4
// spring boot 1.5.2.RELEASE
 
compile('org.springframework.boot:spring-boot-starter-web')
compile('org.springframework.boot:spring-boot-starter-data-jpa')
cs

 

 

1. LocalDataTime 에서 @Temporal 사용 이슈


1) 기존에는 날짜 타입에서는 @Temporal를 추가해서 사용했습니다.


org.hibernate.AnnotationException: @Temporal should only be set on a java.util.Date or java.util.Calendar property


2) @Temporal 제거시,


ClassCastException: java.util.Date cannot be cast to java.time.LocalDateTime



1-1. 왜 이런 이슈가 생긴 것일까?


Java 8은 JPA2.1 이후에 Release 되어, 이에 대한 지원을 하지 않습니다. 


그래서 방법은 


1) JPA AttributeConverter를 구현합니다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
@Converter(autoApply = true)
public class LocalDateTimeAttributeConverter implements AttributeConverter<LocalDateTime, Timestamp> {
 
    @Override
    public Timestamp convertToDatabaseColumn(LocalDateTime locDateTime) {
        return (locDateTime == null ? null : Timestamp.valueOf(locDateTime));
    }
 
    @Override
    public LocalDateTime convertToEntityAttribute(Timestamp sqlTimestamp) {
        return (sqlTimestamp == null ? null : sqlTimestamp.toLocalDateTime());
    }
}
cs

 

2) Hibernate 5에서 소개된 서포트 라이브러리를 이용하여 해결 가능합니다.

 

1
compile('org.hibernate:hibernate-java8:5.0.11.Final')
cs

  

 

2. LocalDateTime 반환 포맷 이슈

 

- 간한다게 LocalDateTime를 반환해보겠습니다.

 

1
2
3
4
5
6
7
8
9
@RestController
@RequestMapping("date")
public class TimeController {
 
    @GetMapping
    public LocalDateTime getLocalDateTime() {
        return LocalDateTime.now();
    }
}
cs

 

- 결과

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
{
  "hour"9,
  "minute"4,
  "nano"377000000,
  "second"55,
  "dayOfMonth"22,
  "dayOfWeek""WEDNESDAY",
  "dayOfYear"81,
  "month""MARCH",
  "monthValue"3,
  "year"2017,
  "chronology": {
  "id""ISO",
  "calendarType""iso8601"
  }
}
cs

 

- LocalDateTime을 Jackson Converter에서 날짜라는 인식을 못하고 객체 자체를 반환하는 듯 합니다.

 


2-1. 해결법(1)

 

1
compile('com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.9.0.pr1')
cs

 

- 결과를 다시 확인해 봅니다. 하지만...

 

1
2
3
4
5
6
7
8
9
[
  2017,
  3,
  22,
  9,
  5,
  50,
  289000000
]
cs

 

- 조금 줄기도 하고 깔끔해지긴 했지만, 우리가 원하는 포맷이 아닙니다. (YYYY-MM-DDTHH:mm:dd:ss.sss)

 


2-2. 해결법(2)

 

- application.properties 에서 이와 같이 추가해줍니다.

 

1
2
3
...
spring.jackson.serialization.WRITE_DATES_AS_TIMESTAMPS=false
...
cs

 

- 다시 결과 확인

 

1
"2017-03-22T09:06:15.198"
cs

 

 

참고

 

- SpringBootJpa

http://www.thoughts-on-java.org/hibernate-5-date-and-time/

'web' 카테고리의 다른 글

Spring Boot - Data JPA & ModelMapper  (414) 2017.04.30
Spring Boot - MyBatis  (396) 2017.04.13
JPA - Persistence Context (영속성 컨텍스트)  (421) 2017.03.16
Spring Boot - Security + JWT  (423) 2017.02.13
Spring Boot - QueryDSL  (410) 2017.01.25
Comments