본문 바로가기


JPA

[JPA] @Convert 사용해서 Object를 Json 형식으로 저장하기

서론

요즘은 다양한 DB 에서 Json 타입을 지원하려고 하지만 하위버전이나 Json 타입을 지원하지 않는 DB 를 사용하고 있는 경우가 있을 것이다. 속성값 같은 건데 모두 column 으로 파는것보다는 Json 타입으로 저장하여 꺼내 쓰는 용도로 사용하면 유용한 경우가 있다. 이런 경우에 매번 가져올 때마다 convert 하지 않아도 Entity 내에서 객체 타입 그대로 사용할 수 있게 해주는 Java Persistence Api 가 있다. 

 

예제

Product 라는 Entity 가 있고 ProductAttribute 를 Json 형식의 text 타입으로 DB Column 에 넣는다고 가정하자.

 

Product Entity 코드

@Entity
public class Product {
...
	@Convert(converter = ProductAttributeConverter.class)
	private ProductAttribute attribute;
...    
}

다른  필수코드들은 생략하고 Convert 할 변수를 어떻게 선언하는지를 나타내었다. @Column 을 안했기때문에 attribute가 column 이름이 된다.

 

ProductAttributeConverter 코드

public class ProductAttributeConverter implements AttributeConverter<ProductAttribute, String> {
	private static final ObjectMapper objectMapper = new ObjectMapper()
		.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

	@Override
	public String convertToDatabaseColumn(ProductAttribute attribute) {
		try {
			return objectMapper.writeValueAsString(attribute);
		} catch (JsonProcessingException e) {
			throw new IllegalArgumentException("error log ...");
		}
	}

	@Override
	public ProductAttribute convertToEntityAttribute(String dbData) {
		try {
			return objectMapper.readValue(dbData, ProductAttribute.class);
		} catch (IOException e) {
			throw new IllegalArgumentException("error log ...");
		}
	}
}

JPA 에 포함된 AttributeConverter 를 구현하면 된다. 내부에서는 Json Serialization 과 Deserialization 을 구현 해주면 되는데 나는 Jackson 을 사용했다.

null 처리 등은 추가적인 코드를 통해 반드시 처리해주는 것이 바람직하다.

 

참고로 내가 사용한 방법으로 다른 처리없이

Serialization 할 때 attribute 로 null 이 들어오면 DB 에는 "null"(String) 이 저장되고 

Deserialization 할 때 dbData 가 "null"(String) 이면 null 이 return 되고 alter 를 치거나해서 NULL 이 데이터에 들어있으면 NPE 가 발생한다. 그러니까 꼭 null 처리를 해야한다.

 

이렇게하면 DB 에는 Json 형식으로 데이터가 채워지게 되고 꺼내서 사용할 때는 Object 로 사용 할 수 있다.

 

참고 : https://ramees.tistory.com/33

끝!