이전 글에 이어 기존의 프로젝트에서도 hypersistence-utils를 사용해 json 형태의 컬럼 값을 코드상으로 파싱해오는 과정을 기록한다.
Project Spec
- Java 1.8
- Spring 2.5.8
- MySQL 8.0.31
- JPA
- hibernate 5.4.33
개요
[{"key_a":5},{"key_b":7},{"key_c":7},{"key_d":7}]
기존 진행되던 프로젝트에서는 로그성으로 응답 결과를 위의 형식으로 컬럼에 저장하고 있었다. 해당 컬럼에 대해 insert나 select 작업 시 컬럼 값을 String으로 받고 코드 로직 내부에서 직접 Json 형식을 파싱해오고 있었는데, 코드의 인지 복잡도가 높아지게 되면서 신규 프로젝트에서 사용했던 hypersistence-utils를 기존의 프로젝트에도 적용하기로 했다.
상세 내용은 위의 포스팅으로 대체하고, java 1.8 기준에서의 환경 설정 위주로 작성한다.
java 1.8 기준 hypersistence-utils 환경설정 하기
hypersistence-utils 공식 github
- 이어지는 환경설정 내용은 모두 해당 링크의 가이드에 따라 적용한 것으로, 추후 작동에 문제가 있는 경우 해당 링크의 최신 알림을 확인한다
build.gradle 의존성 추가
// hypersistence utils - hibernate 5.4.33 기준
implementation 'io.hypersistence:hypersistence-utils-hibernate-52:3.5.0'
implementation 'com.fasterxml.jackson.core:jackson-core:2.15.0'
implementation 'com.fasterxml.jackson.core:jackson-databind:2.15.0'
hypersistence-utils 라이브러리와 함께 json 직렬화에 필요한 jackson을 주입한다.
package-info.java 파일 생성
@TypeDef(
name = "json", typeClass = JsonType.class
)
package io.hypersistence.optimizer;
import io.hypersistence.utils.hibernate.type.json.JsonType;
import org.hibernate.annotations.TypeDef;
import org.hibernate.annotations.TypeDefs;
프로젝트의 루트 경로에 위와 같은 내용을 담은 package-info.java 파일을 생성한다. 생성하지 않아도 무방하나, 생성하지 않을 경우 이후 entity 컬럼 설정 시 약간 번거로워진다.
@Entity
Class 구성 변경
@Getter
@Builder
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor(access = AccessLevel.PRIVATE)
@Entity(name = "TB_JULY_EG")
@TypeDef(name = "json", typeClass = JsonType.class) //기존의 구성에 추가
public class JulyEg {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "IDX")
private Long idx;
...
@Type(type = "json") // 기존의 구성에 추가
@Column(name = "JULY_RESULTS")
private List<Map<String, Integer>> julyResults; // 컬럼 지정 형식에 맞춰 반환 타입 지정
}
1. hypersistence utils를 적용할 Entity 클래스의 클래스 레벨에 @TypeDef(name = "json", typeClass = JsonType.class)
어노테이션 추가
2. hypersistence utils를 적용할 컬럼 (json 형식의 문자열이 저장된 컬럼)의 필드 레벨에 @Type(type = "json")
어노테이션 추가
위의 두 가지 설정을 해당하는 Entity 클래스에 설정해주면 준비가 완료된다.
이후 해당 컬럼을 사용하는 로직에서는 손수 json 파싱 처리를 해줄 필요가 없으며, hypersistence가 그 역할을 위임받아 파싱한 결과를 정한 컬럼 타입으로 반환해준다.
* HibernateException 에러가 뜨는 경우
Caused by: org.hibernate.HibernateException: The propertyClass in JsonTypeDescriptor is null, hence it doesn't know to what Java Object type to map the JSON column value that was read from the database!
환경구성을 마치고, insert 작업까지는 성공했는데 저장된 데이터를 select 하는 과정에서 위의 에러를 마주쳤다. 관련된 정보가 적어 혹시 지정된 컬럼이 DB 상에 null로 저장되어 있는 값이 있어 그런가 해서 초기값도 지정해보고, package-info.java
파일도 일부 수정해보고 했는데 해당 문제는 아니었다.
혹시 위와 같은 에러를 마주친다면 @Entity
클래스 레벨에 @TypeDef(name = "json", typeClass = JsonType.class)
어노테이션이 알맞게 지정되어 있고, package-info.java
파일이 알맞은 경로(프로젝트 루트 경로)에 알맞은 내용을 담고 있는지 확인해보자.
'back-end > spring' 카테고리의 다른 글
spring/ JPA를 이용해 json 형태의 컬럼을 RDB에서 편리하게 다루기 (hypersistence-utils) (1) | 2023.04.14 |
---|---|
spring/ 빈 스코프 (0) | 2022.06.21 |
spring/ 빈 생명주기 콜백 (0) | 2022.06.21 |
spring/ @Autowired 사용 시 조회 대상 빈이 2개 이상인 경우 처리하기 (0) | 2022.06.21 |
spring/ 롬복lombok 사용하기 (0) | 2022.06.21 |