Framework/Spring Boot

엔티티의 필드 타입으로 JSON 사용하기

잔망루피 2023. 1. 24. 16:56
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'io.hypersistence:hypersistence-utils-hibernate-5:3.1.1'

의존성 추가

실행할 때 hibernate 버전 보고,  https://github.com/vladmihalcea/hypersistence-utils

 

 여기에서 맞는 hypersistence-utils를 찾았다.

 

@Type(type="json")
@Column(columnDefinition = "json")
private Profile profile;

json을 필드에 적용했다.

 

@TypeDef(name = "json", typeClass = JsonType.class)

json을 사용하는 필드가 있는 엔티티 클래스 위에 붙여준다.

 

이런식으로 DB에 JSON 타입으로 들어간다.

 

 

Caused by: java.lang.NoSuchMethodError: 'void org.hibernate.boot.model.TypeContributions.contributeType(org.hibernate.usertype.UserType)'

혹시 이런 에러가 뜬다면 상위 버전으로 쓰지 않았나 다시 체크하자!!!

 

 


다른 사람들이 사용한 방법

 

첫 번째 방법) 비정형 데이터

@Type(type="json")
private Map<String, Object> profile;

 

@Transactional
    public void save(String exercise, String work, String movie) {
        var histories = Map.of(
                "exercise", exercise,
                "work", work,
                "movie", movie
        );
        
        var history = UserHistory.of(histories);
        repository.save(history);
    }

JSON 타입을 DB에 저장하는 예시

 

 

참고 👇

https://danawalab.github.io/spring/2022/08/05/Jpa-Json-Type.html

 

JPA로 RDB에 JSON 타입 다루기

JPA를 통해 RDB JSON 타입을 핸들링하는 방법을 알아보겠습니다 with MariaDB

danawalab.github.io

 


🥹 시도했지만 실패

@Convert(converter = ProfileJsonConverter.class)
private Map<String, Object> profile;

다른 사람은 @Column(columnDefinition = "varchar(255)")를 붙여줘서 DB에 VARCHAR 타입으로 저장하던데..

저장하는 형태는 JSON인데 실제 데이터베이스에 저장된 타입은 VARCHAR인 상황?!

java.lang.ClassCastException: class java.util.LinkedHashMap cannot be cast to class com.example.membershipservice.model.Profile (java.util.LinkedHashMap is in module java.base of loader 'bootstrap'; com.example.membershipservice.model.Profile is in unnamed module of loader 'app')

 

 

@Convert(converter = ProfileJsonConverter.class)
private Profile profile;
com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `com.example.membershipservice.model.Profile` (no Creators, like default constructor, exist): cannot deserialize from Object value (no delegate- or property-based Creator)

 

 

@Convert(converter = ProfileJsonConverter.class)
private String profile;
Resolved [org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot deserialize value of type `java.lang.String` from Object value (token `JsonToken.START_OBJECT`); nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize value of type `java.lang.String` from Object value (token `JsonToken.START_OBJECT`)<EOL> at [Source: (org.springframework.util.StreamUtils$NonClosingInputStream); line: 5, column: 17] (through reference chain: com.example.membershipservice.dto.request.UserDto["profile"])]

 

 


 

참고 👇

https://velog.io/@coals_0329/JPA-JSON-in-MySQL-message-converter

 

JPA - JSON in MySQL, message converter

MySQL에 있는 json타입을 JPA로 다루어 보는 방법을 정리해보도록 하겠습니다

velog.io

 

https://goslim56.tistory.com/21

 

JPA 를 사용하여 JSON 문자열을 객체에 매핑하기

Json 문자열 형태를 저장하는 Column 을 가진 Table 을 JPA를 통해 Entity 를 구현할때 단순히 String 형태의 자료형을 사용할 수 있다. 그러나 로직에서 JsonObject를 통해 파싱해야하는 번거로움이 있다. DB

goslim56.tistory.com

 

 

 

반응형