지난 번 글에서는 Java로 converter를 구현했고, 오늘은 Kotlin으로 엔티티를 생성하며 converter를 만들었다.
Survey
@Column(columnDefinition = "mediumText COMMENT '추가 기본 정보 수집'")
@Convert(converter = StringConverter::class)
var custom: List<String>? = null,
@Column(columnDefinition = "mediumText COMMENT '평가 요소'")
@Convert(converter = ElementConverter::class)
var elements: List<SurveyRequest>
StringConverter
package com.seung.survey_kotlin.commons.converter
import com.fasterxml.jackson.core.JsonProcessingException
import com.fasterxml.jackson.core.type.TypeReference
import com.fasterxml.jackson.databind.DeserializationFeature
import com.fasterxml.jackson.databind.ObjectMapper
import jakarta.persistence.AttributeConverter
import org.springframework.stereotype.Component
import java.io.IOException
@Component
class StringConverter :
AttributeConverter<List<String?>?, String> {
override fun convertToDatabaseColumn(attribute: List<String?>?): String {
return try {
mapper.writeValueAsString(attribute)
} catch (e: JsonProcessingException) {
throw IllegalArgumentException()
}
}
override fun convertToEntityAttribute(dbData: String): List<String?>? {
return try {
mapper.readValue(dbData, object : TypeReference<List<String?>?>() {})
} catch (e: IOException) {
throw IllegalArgumentException()
}
}
companion object {
private val mapper: ObjectMapper = ObjectMapper()
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
.configure(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES, false)
}
}
ElementConverter
package com.seung.survey_kotlin.commons.converter
import com.fasterxml.jackson.core.JsonProcessingException
import com.fasterxml.jackson.core.type.TypeReference
import com.fasterxml.jackson.databind.DeserializationFeature
import com.fasterxml.jackson.databind.ObjectMapper
import com.seung.survey_kotlin.commons.dto.request.survey.SurveyRequest
import jakarta.persistence.AttributeConverter
import jakarta.persistence.Converter
@Converter
class ElementConverter :
AttributeConverter<List<SurveyRequest?>?, String> {
private val mapper: ObjectMapper = ObjectMapper()
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
.configure(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES, false)
override fun convertToDatabaseColumn(attribute: List<SurveyRequest?>?): String {
return try {
mapper.writeValueAsString(attribute)
} catch (e: JsonProcessingException) {
throw IllegalArgumentException()
}
}
override fun convertToEntityAttribute(dbData: String?): List<SurveyRequest?>? {
val typeReference: TypeReference<List<SurveyRequest?>?> = object : TypeReference<List<SurveyRequest?>?>() {}
return try {
mapper.readValue(dbData, typeReference)
} catch (e: JsonProcessingException) {
throw RuntimeException(e)
}
}
}
Java와 Kotlin으로 구현했을 때의 공통점
1. 기능
- 두 언어 모두 JPA AttributeConverter 인터페이스를 구현하여 엔티티 필드 데이터를 JSON 문자열로 직렬화/역직렬화하는 기능을 제공한다.
- Jackson 라이브러리를 사용해 JSON 처리(객체 <-> JSON 문자열)를 수행한다.
2. 구조
- convertToDatabaseColumn과 convertToEntityAttribute 메서드를 구현하며, 동일한 역할을 한다.
- 둘 다 ObjectMapper를 이용해 JSON 변환을 간결하게 처리한다.
3. 사용 방법
- JPA 어노테이션 @Converter를 사용하여 데이터베이스와의 타입 매핑을 담당한다.
차이점
항목 | Kotlin 구현 | Java 구현 |
문법 | Kotlin의 간결한 문법 사용 | Java의 명시적이고 정형화된 문법 사용 |
널 처리 | nullable 타입(List<String?>?)으로 표현 | 널 허용을 별도로 처리하지 않고 일반 타입 사용 |
익명 클래스 | object : TypeReference<List<...>>() 문법 사용 | Java에서 익명 클래스를 생성 (new TypeReference<List<...>>()) |
ObjectMapper 초기화 | private val mapper = ObjectMapper() 간결하게 정의 | private final ObjectMapper mapper = new ObjectMapper() 명시적 정의 |
예외 처리 | try-catch에서 예외 타입 없이 처리 가능 (IllegalArgumentException()) | 예외 객체를 명시적으로 전달 (new IllegalArgumentException(e)) |
가독성 | 함수형 스타일과 생략된 키워드로 간결함 | 정형화된 문법으로 명확함 |
결론
- Kotlin : 더 간결하고 현대적인 문법으로 생산성을 높이며, 널 안정성을 기본 제공
- Java : 널리 사용되는 표준 언어로, 보편적이고 신뢰할 수 있는 도구와 호환성 제공
'개발' 카테고리의 다른 글
[개발] Converter 설정하기 - Java (0) | 2024.11.19 |
---|---|
Kotlin에 Querydsl 적용하기 - 24.11.14 기준 (0) | 2024.11.14 |
[개발] IntelliJ와 GitHub 연결하기 (1) | 2024.10.21 |
[개발] 사이드 프로젝트 시작 (1) | 2024.10.10 |
[에러] swagger로 테스트 시 LocalDateTime typeMisMatch (0) | 2024.06.26 |