본문 바로가기
Spring

@Id와 @Convert가 같이 있을 때 정상 동작하지 않는 이유

by jayden jayden-lee 2021. 8. 16.

문제 상황

Entity에서 테이블의 컬럼이 String 타입인 것을 LocalDate 타입으로 변경하려고 했습니다. 기존에 정의 되어 있는 Converter 구현체가 있었기 때문에 @Convert 어노테이션을 사용해서 적용했는데, 실제로 Converter로 로직을 타지 않고 java.sql.Date 클래스의 valueOf 메서드가 호출되고 있었습니다.

java.sql.Date 클래스의 valueOf 메서드는 문자열 날짜 값을 파싱할 때, 날짜 형식이 yyyy-[m]m-[d]d가 아니면, IllegalArgumentException 에러를 던지고 있습니다. 테이블에 저장되어 있는 값이 마침 yyyymmdd로 저장되어 있어서 계속 에러가 발생했습니다.

 

class LocalDateConverter : AttributeConverter<LocalDate?, String?> {
	// db -> entity, entity -> db 값 변환 코드
}

class Entity (
    @Id
    @Convert(LocalDateConverter::class)
    @Column(name = "CUSTOM_DATE")
    val date: LocalDate
)

 

문제 원인

JPA 문서에 명시 되어 있는 것처럼 converter는 기본 속성에는 적용되지만, Id 속성에는 적용하지 못한다고 되어 있습니다. Id 속성 이외에도 버전, 관계 등이 있습니다.

JPA persistence api 2.2 doc

참고 문서: java persistence api 2.2 oracle doc, p122

 

해결 방법

1. @IdClass 사용해서 @Convert를 적용하기

https://stackoverflow.com/questions/44069361/convert-on-id-field/46148057#46148057

 

@Convert on @Id field

I'm trying to @Id @Column(name = "MY_ID_FIELD") @Convert(converter = IdConverter.class) private Long id; IdConverter is: @Converter public class IdConverter implements AttributeConverter<long,< p=""> </long,<>

stackoverflow.com

2. db 특성을 사용해서 row_id에 entity의 @Id로 설정해서 convert 적용하기

class Entity (
    @Id
    @Column(name = "ROWID")
    val rowId: String,

    @Column(name = "CUSTOM_DATE")
    @Convert(converter = LocalDateConverter::class)
    val date: LocalDate
)

 

댓글0