Interface-based에서 Timestamp로 선언된 컬럼을 ZonedDateTime으로 변환하여 사용하는 방법.
에러
Cannot project java.sql.Timestamp to java.time.ZonedDateTime. Target type is not an interface and no matching Converter found!
java.lang.UnsupportedOperationException: Cannot project java.sql.Timestamp to java.time.ZonedDateTime. Target type is not an interface and no matching Converter found!
CREATE TABLE `table` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`created` datetime NOT NULL COMMENT '생성일'
PRIMARY KEY (`id`),
)
select rows : 7, '2022-12-12 11:09:13'
interface DTO {
val id: Int
val created: ZonedDateTime
}
@Query( value = "SELECT * FROM table", nativeQuery = true)
fun findAll() : List<DTO>
Interface-based Projection에서 ZonedDateTime으로 설정된 경우 Converter가 정상적으로 동작하지 않아 오류가 발생합니다.
springboot 2.4.0 미만의 버전에서는 DefaultConversionService.getSharedInstance()에 추가하고
2.4.0부터는 reflection으로 ProxyProjectionFactory에 Converter을 추가합니다.
datetime, timstamp 이외 숫자 형태로 생성된 컬럼도 비슷한 유형으로 대응할 수 있습니다.
@Component
class ProxyProjectionFactoryDefaultConversionServiceInitializer : InitializingBean {
override fun afterPropertiesSet() {
val aClass = Class.forName("org.springframework.data.projection.ProxyProjectionFactory")
val field: Field = aClass.getDeclaredField("CONVERSION_SERVICE").apply {
isAccessible = true
}
(field.get(null) as GenericConversionService).apply {
addConverter(TimestampToZonedDateTimeConverter())
}
}
}
class TimestampToZonedDateTimeConverter :
org.springframework.core.convert.converter.Converter<Timestamp, ZonedDateTime> {
override fun convert(source: Timestamp): ZonedDateTime {
return source.toLocalDateTime().toZonedDateTime()
}
}
fun LocalDateTime.toZonedDateTime(){
// 변환 로직
}
Mysql datetime, timestamp 차이
timestamp는 세션에 설정된 timezone이 반영되며 datetime은 반영되지 않는다.
JDBC serverTimezone 속성
jdbc:mysql://mysql:3306/db?serverTimezone=UTC
JDBC url 파라미터에 serverTimezone포함되어 있다면 serverTimezone의 값으로 Timezone instance을 생성하여 connection 생성하고 파라미터가 존재하지 않는다면 Application의 Timezone으로 생성한다.
참고
https://kim-jong-hyun.tistory.com/132
https://studyposting.tistory.com/89
'DEVELOPE' 카테고리의 다른 글
NoHandlerFoundException ControllerAdvice에서 제어하기 (0) | 2023.08.10 |
---|
댓글