JPA 에서 MySql Json 타입 사용하기 (+ hibernate 6 이상)

잼구·2023년 12월 5일
1

Mysql 은 버전 5.7 이상부터 type 으로 Json 을 지원합니다.
RDBMS 의 목적과 반대되는 type 이라 많이 사용하진 않지만, 가끔 사용 할때가 있습니다.

이때 JPA 에서 Json 타입을 어떻게 선언하는지 hibernate 6 이상, 이하로 나누어 살펴보겠습니다.


hibernate 6 이하

기준 환경

  • spring boot 버전 : 'org.springframework.boot' version '2.7.10'
  • Java 버전 : 11
  • spring-boot-starter-data-jpa : 2.7.10
    Hibernate-core 버전 : 5.6.15.Final

구현

@Entity
@TypeDef(name = "json", typeClass = JsonStringType.class)
public class Entity {
    @Column(name = "db_filed", columnDefinition = "json")
    @Type(type = "json")
    private List<String> imageUrl;
}
  • @TypeDef
    org.hibernate.usertype.UserType 을 구현한 (기본 구현도 존재) 사용자 정의 타입(user-defined type)을 등록하는 데 사용하는 어노테이션.
    즉, @Type 정의를 지정하는 데 사용.
    이를 통해 Hibernate에 새로운 타입을 등록하고, 이 타입을 엔티티의 속성에 적용할 수 있음.
    하이버네이트에서 제공 하는 예시

pakage-info.java 파일에 적어서 패키지 레벨로도 사용 가능.

@TypeDefs({
        @TypeDef(name = "json", typeClass = JsonStringType.class),
        // 다른 공통 타입 정의들...
})

package com.example.user;
  • @Type
    필드나 메소드에 사용자 정의 타입을 적용하는 데 사용하는 어노테이션.
    즉, @TypeDef에서 정의한 타입 또는 Hibernate에서 제공하는 타입을 실제 속성에 적용할 때 사용.
    하이버네이트에서 제공 하는 예시

hibernate 6 이상

기준 환경

  • spring boot 버전 : 'org.springframework.boot' version '3.1.3'
  • Java 버전 : 17
  • spring-boot-starter-data-jpa : 3.1.3
    Hibernate-core 버전 : 6.2.7.Final

구현

@Entity
public class Entity {
    @Column(name = "db_filed", columnDefinition = "json")
    @JdbcTypeCode(SqlTypes.JSON)
    private List<String> imageUrl;
}

Compositional basic mapping 중 JdbcType에 해당되는 어노테이션 사용.
Compositional basic mapping 설명

하이버네이트는 명시적으로 해당 어노테이션이 붙어 있는 경우에만 Json 을 사용한다.
직렬화/역직렬화에 사용되는 JSON 라이브러리는 자동으로 감지되지만, hibernate.type.json_format_mapper를 설정하여 재정의할 수 있음.
하이버네이트에서 제공 하는 예시

해당 버전부터 deprecated 되어 사용 불가

  • @TypeDef
  • @TypeDefs

위 어노테이션이 deprecated 되어 사용자 정의 타입을 정의하는 방식도 변경.
-> MetadataContributor 인터페이스를 구현하는 방식으로 사용자 정의 타입을 등록.

둘다 가능

JPA 2.1 이상을 사용하는 경우 AttributeConverter를 사용.

@Convert(converter = ListConverter.class)
private List<String> imageUrl;

AttributeConverter 를 구현한 컨버터를 등록해서 직렬화, 역직렬화를 직접 구현.

결론

hibernate 6 이상 부터는 @TypeDef 를 쓸 수 없기 때문에 제공 되었던 UserType 들은 Compositional basic mapping 로 대체하고, AttributeConverter 를 사용하라고 권고한다.
@Type 은 복잡한 매핑을 가능하게 하지만 간단한 경우는 위 두가지 경우로 대체 가능하다.


ref

https://www.baeldung.com/hibernate-persist-json-object
https://docs.jboss.org/hibernate/orm/6.0/userguide/html_single/Hibernate_User_Guide.html
https://prateek-ashtikar512.medium.com/how-to-handle-json-in-mysql-4adaeeb1d42f

profile
잼구입니다

0개의 댓글