Spring Boot:从PostgreSQL JSON列反序列化POJO时忽略未知字段
解决Hibernate JsonBinaryType反序列化JSONB时忽略未知属性的问题
针对PostgreSQL jsonb字段映射到DTO时因第三方API新增属性导致的UnrecognizedPropertyException,以下是几种可行的解决方案:
方案1:自定义JsonBinaryType类型
创建一个继承JsonBinaryType的自定义类型,在构造方法中配置忽略未知属性的ObjectMapper:
public class CustomJsonBinaryType extends JsonBinaryType { public CustomJsonBinaryType() { super(); ObjectMapper mapper = new ObjectMapper(); // 关闭未知属性触发反序列化失败的特性 mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); setObjectMapper(mapper); } }
然后在实体类中使用这个自定义类型:
@Entity @TypeDef(name = "customJsonb", typeClass = CustomJsonBinaryType.class) public class A { // 其他字段 @Type(type = "customJsonb") @Column(name = "jsonBody", columnDefinition = "jsonb") private SomeModel jsonBody; }
方案2:全局配置Hibernate的Jackson ObjectMapper
通过Spring Boot的HibernatePropertiesCustomizer全局配置Hibernate使用的ObjectMapper:
import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import org.hibernate.type.jackson.JacksonJsonBinaryType; import org.springframework.boot.autoconfigure.orm.jpa.HibernatePropertiesCustomizer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class HibernateJacksonConfig { @Bean public HibernatePropertiesCustomizer hibernateJacksonCustomizer() { return hibernateProperties -> { ObjectMapper objectMapper = new ObjectMapper(); objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); // 为JsonBinaryType指定配置好的ObjectMapper hibernateProperties.put(JacksonJsonBinaryType.class.getName() + ".objectMapper", objectMapper); }; } }
方案3:通过@Type参数指定自定义ObjectMapper
在实体类的@Type注解中直接指定提供ObjectMapper的类:
@Entity @TypeDef(name = "jsonb", typeClass = JsonBinaryType.class) public class A { // 其他字段 @Type(type = "jsonb", parameters = { @Parameter(name = JsonBinaryType.OBJECT_MAPPER, value = "com.example.config.CustomObjectMapper") }) @Column(name = "jsonBody", columnDefinition = "jsonb") private SomeModel jsonBody; }
对应的CustomObjectMapper类需要提供一个获取配置好的ObjectMapper的方法:
import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; public class CustomObjectMapper { public static ObjectMapper get() { ObjectMapper mapper = new ObjectMapper(); mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); return mapper; } }
说明
@JsonIgnoreProperties(ignoreUnknown = true)无效的原因是:Hibernate的JsonBinaryType默认使用的ObjectMapper并未继承Spring Boot全局配置的序列化规则,需要单独为Hibernate的JSON类型配置忽略未知属性的特性。
内容的提问来源于stack exchange,提问作者Dezrhog
相关产品推荐
相关产品推荐

