@Id와 @Convert가 같이 있을 때 정상 동작하지 않는 이유
문제 상황
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 속성 이외에도 버전, 관계 등이 있습니다.
참고 문서: 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
)