PostgreSQL을 Spring Data JPA 로 다루기

tkppp·2022년 4월 14일
0

PostgreSQL의 특이 데이터 타입

일반적으로 많이 사용하는 Mysql과 다르게 PostgreSQL은 다양한 데이터 타입을 지원한다. 예를들면 배열 타입, JSON 타입, JSON Binary 타입 등을 지원한다.

하지만 JPA의 구현체인 Hibernate에서 해당 데이터 타입에 대한 컬럼 타입을 기본으로 지원하지 않기 때문에 사용하기 위해서는 컬럼 타입을 정의하여 사용할 컬럼 타입과 매핑해주어야 한다.

하이버네이트 사용자 정의 데이터 타입 매핑

컬럼 타입을 정의하려면 UserType 인터페이스를 구현하면 된다. 하지만 이는 매우 귀찮은 일이므로 라이브러리를 사용한다. 직접 UserType을 구현해보고 싶으면 여기를 참조하자.

의존성

implementation("com.vladmihalcea:hibernate-types-52:2.16.0")

구현

import com.vladmihalcea.hibernate.type.array.ListArrayType
import org.hibernate.annotations.TypeDef
import javax.persistence.*
import org.hibernate.annotations.Type

@Entity
@TypeDef(name="list-int", typeClass = ListArrayType::class)
class Summoner(
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    val id: Long? = null,

    @Column(nullable = false)
    val puuid: String,

    @Column(nullable = false)
    var name: String,

    @Column(nullable = true)
    var recentMatchId: String,

    @Type(type = "list-int")
    @Column(columnDefinition = "integer[]")
    var analysisResults: List<Int>
)

먼저 @TypeDef 어노테이션으로 컬럼 타입을 정의하고 지원하지 않는 타입의 컬럼을 정의할 때 @Type 어노테이션으로 위에서 정의한 컬럼 타입을 지정하고 @Column 어노테이션으로 데이터베이스에 들어갈 컬럼의 타입을 정의함으로써 하이버네이트가 컬럼 타입으로 지원하지 않는 List<Int> 와 PostgreSQL의 integer[] 을 매핑했다.

테스트

@SpringBootTest
class SummonerRepositoryTest(
    @Autowired private val summonerRepository: SummonerRepository
) {

    @AfterEach
    fun tearDown(){
        summonerRepository.deleteAll()
    }

    @Test
    @DisplayName("Create 테스트")
    fun createTest() {
        // given
        val puuid = "puuid"
        val name = "쳇바퀴 속 다람쥐"
        val recentMatchId = "match_id"
        val analysisResult = listOf(1,4,5,6)
        val summoner = Summoner(
            puuid = puuid, name = name, recentMatchId = recentMatchId, analysisResults = analysisResult
        )

        // when
        val result = summonerRepository.save(summoner)

        // then
        println(result.id)
        assertThat(result.puuid).isEqualTo(puuid)
        assertThat(result.name).isEqualTo(name)
        assertThat(result.recentMatchId).isEqualTo(recentMatchId)
        assertThat(result.analysisResults).isEqualTo(analysisResult)
    }
}

테스트를 실행해보면 새 엔티티의 삽입이 정상적으로 되는 것을 확인할 수 있다.

참고

https://vladmihalcea.com/postgresql-array-java-list/
https://www.baeldung.com/hibernate-custom-types

0개의 댓글