JPA - Hibernate ObjectMapper
ํ์ฌ ์กฐ์ง์์ JPA ๋ผ๋ ORM ๊ธฐ์ ์ ํ์ฉํ๊ณ ์์ง ์์ง๋ง ์ค๋๋ง์ JPA๋ผ๋ ๊ธฐ์ ์ ํตํด ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ํต์ ํด๋ณด๊ณ ๊ฒฝํํ๊ฒ ๋ ๋ฌธ์ ์ ํด๊ฒฐ๋ฐฉ๋ฒ์ ๋ํด ๊ณต์ ํด๋ณด๋ ค๊ณ ํฉ๋๋ค. MySQL ๋๋ PostgreSQL ์์๋ JSON ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๊ณ ์ฒ๋ฆฌํ ์ ์๋ ํจ์๋ฅผ ์ ๊ณตํ๊ณ ์์ต๋๋ค. PostgreSQL์์ JSONB ์ปฌ๋ผ์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๋ ๊ณผ์ ์์ ๋ชจ๋ธ ํด๋์ค์ ๋ง์ง ์์ ํ๋๊ฐ ํฌํจ๋ ๋ ๋ฐ์ํ ์ ์๋ UnrecognizedPropertyException ์์ธ๋ฅผ ๊ฒฝํํ๋๋ฐ์.
DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES
๋จผ์ , ์คํ๋ง ๋ถํธ ํ๋ก์ ํธ์์ ์๋ ๊ตฌ์ฑ์ ํตํด ๊ธฐ๋ณธ์ ์ผ๋ก ์ ๊ณตํ๋ ObjectMapper์ ๋ํด์ ์ ์ ์๋ ํ๋๊ฐ ํฌํจ๋ ๊ฒฝ์ฐ ์ค๋ฅ๋ก ์ฒ๋ฆฌํ์ง ์๋๋ก ์๋์ ๊ฐ์ด ๋ค์ํ ๋ฐฉ๋ฒ์ผ๋ก ์ค์ ํ ์ ์๋ค๋ ๊ฒ์ ๋๋ถ๋ถ ์ธ์งํ๊ณ ์๋ ์ ๋ณด๋ผ๊ณ ์๊ฐ๋ฉ๋๋ค.
- @JsonIgnoreProperties(ignoreUnknown = true)
- DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES
- spring.jackson.deserialization.fail-on-unknown-properties
spring.jackson.deserialization.FAIL_ON_UNKNOWN_PROPERTIES: false
ํ์ฌ ์กฐ์ง์ ํ๋ก์ ํธ์์๋ Jackson2ObjectMapperBuilder๋ฅผ ๋น์ผ๋ก ์ง์ ๋ฑ๋กํ์ฌ ์ปค์คํ ์ต์ ์ด ์ ์ฉ๋ ์ฌ์ฉํ๊ณ ์์ด์!
JPA ์์๋ FAIL_ON_UNKNOWN_PROPERTIES ์ค์ ์ด ์ ์ฉ๋์ง ์์
Caused by: java.lang.IllegalArgumentException: The given string value: {"active": true, "mfa_type": "email"} cannot be transformed to Json object
... 79 common frames omitted
Caused by: com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "mfa_type" (class kr.kdev.demo.UserEntity$Metadata), not marked as ignorable (one known property: "active"])
at [Source: REDACTED (`StreamReadFeature.INCLUDE_SOURCE_IN_LOCATION` disabled); line: 1, column: 31] (through reference chain: kr.kdev.demo.UserEntity$Metadata["mfa_type"])
์ ์ค๋ฅ ๋ฉ์์ง๋ JPA ์์ JSONB ์ปฌ๋ผ์ ์ฌ๋ฐ๋ฅด์ง ์์ ํ๋๊ฐ ํฌํจ๋ JSON์ ๋ชจ๋ธ ํด๋์ค๋ก ๋ณํํ๋ ๊ณผ์ ์์ ๋ฐ์ํ ๊ฒ ์ ๋๋ค. ์์, ์คํ๋ง ๋ถํธ์์ ๊ธฐ๋ณธ์ผ๋ก ์ ๊ณตํ๋ ObjectMapper์ FAIL_ON_UNKNOWN_PROPERTIES ๋ฅผ ์ค์ ํ๋๋ฐ ์ ์ ์ฉ์ด ์๋๋๊ฑธ๊น์? ๊ทธ ์ด์ ๋ JSON ๋ฐ์ดํฐ๋ฅผ ์ฒ๋ฆฌํ๊ธฐ ์ํด์ ์ ์ฉํ Hypersistence Utils์์ ์ฌ์ฉํ๋ JacksonJsonFormatMapper ์์ ์คํ๋ง ๋น ํฉํ ๋ฆฌ์์ ๊ด๋ฆฌํ๋ ObjectMapper ์ธ์คํด์ค๊ฐ ์๋๊ธฐ ๋๋ฌธ์ ๋๋ค.
PostgreSQL JSONB ์ปฌ๋ผ ๋งคํ ์ ObjectMapper ๋ณ๊ฒฝํ๋ ๋ฐฉ๋ฒ
JPA ์์ JSON ๋ฐ์ดํฐ ์ฒ๋ฆฌ ์ ์ฌ์ฉํ๋ ObjectMapper๋ฅผ ์คํ๋ง ๋ถํธ์์ ๋น์ผ๋ก ๊ด๋ฆฌํ๋ ์ธ์คํด์ค๋ก ๋ณ๊ฒฝํ๋ ค๋ฉด ์๋์ ๊ฐ์ ๋ฐฉ๋ฒ๋ค์ ํ์ฉํ ์ ์์ต๋๋ค.
- ObjectMapperWrapper
- hibernate.types.jackson.object.mapper + ObjectMapperSupplier
- HibernatePropertiesCustomizer
@Bean
public HibernatePropertiesCustomizer jsonFormatMapperCustomizer(ObjectMapper objectMapper) {
return (properties) -> properties.put(AvailableSettings.JSON_FORMAT_MAPPER,
new JacksonJsonFormatMapper(objectMapper));
}
์ ๋ ์คํ๋ง ๋ถํธ ์ด์ ํฐ์ผ์์ ์๋ ค์ฃผ๋ HibernatePropertiesCustomizer๋ก ObjectMapper๋ฅผ ์ ์ฉํ์ต๋๋ค.