Yeonnnnny

[TIL] JSONB 타입의 변수를 가진 엔티티 (Spring Boot - PostgreSQL) 본문

TIL

[TIL] JSONB 타입의 변수를 가진 엔티티 (Spring Boot - PostgreSQL)

yeonny_do 2025. 2. 15. 00:08

 

 

앞선 게시물에서 언급한 JSONB타입의 변수를 가진 엔티티를 만들려고 할 때,

많은 어려움이 들었다. 

 

일단 하고 싶은게 휴무일을 (월요일, 화요일, 수요일, 목요일, 금요일, 토요일, 일요일) 중에서 복수로 고를 수 있게 하여 DB에 저장하는 것이었어서, 해당 컬럼의 타입을 JSONB로 설정을 한거다. 

 

그런데 Spring에서 엔티티를 작성할때 휴무 요일에 대한 값을 ENUM 타입으로 쓰고 싶은 욕심이 들었다. 

어쩌면 좋을까나 .... 일단 시도해보았다. 

 

먼저, closedDays라는 변수의 타입을 Enum으로 할 것이기 때문에 ENUM 먼저 만들어줬다.

 


1. ClosedDays Enum 생성

 

📌  휴무일을 Enum 타입으로 정의

// import는 생략..

public enum ClosedDays{

    MONDAY("월요일"),
    TUESDAY("화요일"),
    WEDNESDAY("수요일"),
    THURSDAY("목요일"),
    FRIDAY("금요일"),
    SATURDAY("토요일"),
    SUNDAY("일요일");


	private final String description;
    
    ClosedDays(String description){
    	this.description = description;
    }
    
    @JsonValue
    public String getDescription(){
    	return description;
    }
    
    @JsonCreator
    public static ClosedDays from(String value){
    	retrun Arrays.stream(ClosedDays.values())
        	.filter(day -> day.description.equals(value))
            .findFirst()
            .orElseThrow(() ->
            	new IllegalArgumentException("존재하지 않는 휴무일: "+value)
            );
    }
}

 

✔️ @Jsonvalue : JSON 직렬화 시 "월요일"과 같은 문자열 값으로 반환

✔️ @JsonCreator : JSON 역직렬와 시 "월요일"을 ClosedDays.MONDAY로 변환

✔️ Enum을 사용해 휴무일 값을 강제 하므로 데이터 무결성 보장

 

 

2. Store.java 의 closedDays 필드에 (JSON+Enum) 적용

 

public class Store {
	
    //...
    
    @JdbcTypeCode(SqlTypes.JSON)
    @Column(columnDefinition = "jsonb")
    @Convert(convert=ClosedDaysConverter.class)
    private List<ClosedDays> closedDays; // 휴무일을 JSONB로 저장 (Enum 리스트)
    
    //...
}

 

✔️ List<ClosedDays> 타입을 JSONB로 저장

✔️ @JdbcTypeCode(SqlTypes.JSON) : Hibernate에서 JSONB 타입으로 매핑

✔️ @Convert(converter = ClosedDaysConverter.class) : Enum 리스트를 JSON으로 변환

 

 

 

3. ClosedDaysConverter.java (Enum <-> JSON 변환)

 

📌 Hibernate에서 List<ClosedDays> 를 JSON으로 변환하는 컨버터 추가

// import 생략

@Converter
public class ClosedDaysConverter implements AttributeConverter<List<ClosedDays>, String>{

    private static final ObjectMapper objectMapper = new ObjectMapper();
    
    @Override
    public String convertToDatabaseColumn(List<ClosedDays> attribute){
    	try{
        	return objectMapper.writeValueAsString(attribute);
        }catch(JsonProcessingException e){
        	throw new RuntimeException("휴무일 변환 중 오류 발생", e);
        }
    }

	@Override
    public List<ClosedDays> convertToEntityAttrebute(String dbData){
    	try{
        	return Arrays.asList(objectMapper.readValue(dbData, ClosedDays[].class));
        }catch(JsonProcessingException e){
        	throw new RuntimeException("휴무일 변환 중 오류 발생", e);
        }
    }

}

 

✔️ JSON 변환기(ClosedDaysConverter)를 사용해 List<ClosedDays>를 JSON 문자열로 변환 후 저장

✔️ PostgreSQL JSONB를 활용해 휴무일을 저장할 수 있음

 

 

이런 식으로 하면 될 것 같다.. 복잡스럽긴한데 일단 사용을 해보자꾸나~