본문 바로가기
개발

[개발] Survey 엔티티 생성 및 Converter 설정하기 - Kotlin

by 공덕뉸나 2024. 11. 20.

지난 번 글에서는 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 : 널리 사용되는 표준 언어로, 보편적이고 신뢰할 수 있는 도구와 호환성 제공