본문 바로가기
WEB/Spring JPA

@TypeDef, @Type 전환 SpringBoot 3.x 마이그레이션 가이드

by 정권이 내 2025. 4. 15.

@TypeDef (Hibernate 5.x)

@TypeDef는 Hibernate에서 사용자 정의 데이터 타입을 정의할 때 사용하는 어노테이션입니다.

JPA에서는 문자열, 숫자, 날짜 등 기본적인 타입만 매핑할 수 있기 때문에, JSON, Enum과 같은 복잡한 타입을 처리하기 위해서는 Hibernate에서 해당 타입을 어떻게 매핑할 것인지 명시적으로 알려줘야 합니다.

이럴 때 @TypeDef를 사용하여 사용자 정의 타입을 등록하고, 실제 필드에는 @Type을 사용하여 적용합니다.

 

언제 사용하는가?

엔티티 필드가 기본적인 타입이 아닌 경우, Hibernate는 해당 필드를 어떻게 DB에 저장하고 다시 Java 객체로 매핑할지 알 수 없습니다. 이런 경우 @TypeDef로 사용자 정의 타입을 등록하고, @Type을 이용하여 해당 필드에 타입 매핑 방식을 지정해줍니다.

import com.vladmihalcea.hibernate.type.json.JsonType;
import com.vladmihalcea.hibernate.type.array.StringArrayType;
import org.hibernate.annotations.Type;
import org.hibernate.annotations.TypeDef;
import org.hibernate.annotations.TypeDefs;

import javax.persistence.*;
import java.util.Map;

@Entity
@TypeDefs({
    @TypeDef(name = "json", typeClass = JsonType.class),
    @TypeDef(name = "string-array", typeClass = StringArrayType.class)
})
public class Product {

    @Id
    private Long id;

    @Type(type = "json")
    @Column(columnDefinition = "jsonb")
    private Map<String, Object> metadata;

    @Type(type = "string-array")
    @Column(columnDefinition = "text[]")
    private String[] tags;
}
  • @TypeDefs는 엔티티 안에서 여러 개의 사용자 정의 타입을 등록할 때 사용합니다.
  • @TypeDef에서 지정한 name 값을 @Type 어노테이션의 type 속성에서 사용합니다.

 

@Type (Hibernate 6.x / Spring Boot 3.x)

Spring Boot 3.x로 업그레이드되면서 Hibernate 6.x가 적용되었고, @TypeDef는 더 이상 사용하지 않게 되었습니다.

이제는 각 필드에 직접 @Type 어노테이션을 사용하여 타입 클래스를 지정하는 방식으로 바뀌었습니다.

import com.vladmihalcea.hibernate.type.json.JsonType;
import org.hibernate.annotations.Type;

import javax.persistence.*;
import java.util.Map;

@Entity
public class UserProfile {

    @Id
    private Long id;

    @Type(JsonType.class)
    @Column(columnDefinition = "jsonb")
    private Map<String, Object> attributes;

    // getter, setter
}
  • 클래스 기반으로 타입을 직접 선언하기 때문에 코드가 더 간결하고 가독성이 향상됩니다.

 

사용 가능한 타입 클래스

@Type 어노테이션에서 사용할 수 있는 클래스는 Hibernate에서 제공하거나 외부 라이브러리에서 제공하는 타입 클래스입니다. 일반적으로 org.hibernate.type.BasicType 또는 org.hibernate.usertype.UserType 인터페이스를 구현하고 있어야 합니다.

 

1. Json

com.vladmihalcea.hibernate.type.json.JsonType
  • 의존성: hibernate-types-55 또는 hibernate-types-60
  • 지원 DB: PostgreSQL (jsonb), MySQL (json), Oracle (json 또는 clob)
  • Java 타입: Map, List, DTO 등

 

2. Array

com.vladmihalcea.hibernate.type.array.StringArrayType
com.vladmihalcea.hibernate.type.array.IntArrayType
com.vladmihalcea.hibernate.type.array.LongArrayType
  • 지원 DB: PostgreSQL의 배열 타입 (text[], int[] 등)
  • Java 타입: String[], int[], long[] 등

 

3. Enum

com.vladmihalcea.hibernate.type.basic.PostgreSQLEnumType
  • 지원 DB: PostgreSQL native enum
  • Java 타입: Enum

 

예시 코드

@Type(JsonType.class)
@Column(columnDefinition = "jsonb")
private Map<String, Object> metadata;

@Type(StringArrayType.class)
@Column(columnDefinition = "text[]")
private String[] tags;

@Type(PostgreSQLEnumType.class)
@Column(columnDefinition = "my_enum")
@Enumerated(EnumType.STRING)
private MyStatus status;

 

DB 종류별 매핑 정리

  • PostgreSQL은 JSON, 배열, ENUM, Range 등 다양한 복합 타입을 네이티브로 지원해서 활용도가 높습니다.
  • MySQL은 PostgreSQL처럼 json, enum은 지원하지만 배열은 직접 지원하지 않습니다.
  • Oracle은 JSON을 CLOB 또는 JSON 타입으로 저장할 수 있고, 배열이나 enum에 대한 직접 지원은 부족하지만 우회 가능합니다.
DBJSON 매핑배열 매핑ENUM 매핑
PostgreSQLjsonb + JsonTypetext[] + ArrayTypeenum + PostgreSQLEnumType
MySQLjson + JsonTypeJSON 배열로 우회기본 enum 처리 가능 (@Enumerated)
Oraclejson or clob + JsonTypeJSON 배열로 우회기본 enum 처리 가능 (@Enumerated)

 

정리

  • @TypeDef는 Hibernate 5에서 사용자 정의 타입을 정의하기 위한 어노테이션입니다.
  • Spring Boot 3.x부터 Hibernate 6.x가 적용되면서 @TypeDef 없이 필드 단위의 @Type(클래스명.class) 방식으로 변경되었습니다.
  • 마이그레이션 시 @TypeDef는 제거하고, 각 필드에 @Type 어노테이션을 통해 타입 클래스를 직접 지정하면 됩니다.
  • JSON, 배열, ENUM 등 복잡한 데이터 타입도 Hibernate의 확장 기능을 통해 손쉽게 매핑할 수 있습니다.
반응형

댓글