SpringBoot反序列化@Embedded属性报Unrecognized field异常
问题原因与修复方案
问题产生原因
报错核心是Jackson反序列化阶段未识别到Product类的price属性,和JPA的@Embedded持久化配置没有关系。当price是基本数值类型时,Jackson对基本类型可直接通过反射绑定值,即使配置有瑕疵也能正常运行,但换成自定义引用类型后,对类结构完整性、配置正确性的要求更高,就会触发属性识别失败的报错,具体诱因包括3点:
- Lombok注解和手动写的构造器冲突、或IDE未开启Lombok注解处理,导致
price字段的getter/setter未正常生成,Jackson无法访问该字段 - 代码中手动实例化的
ObjectMapper是原生空配置实例,没有加载SpringBoot预配置的序列化/反序列化扩展模块,对自定义值对象的属性识别存在兼容问题 - Jackson注解配置错误:
@JsonIgnoreProperties(ignoreUnknown=true)是类级别注解,错误标注在Price类的GST字段上完全不生效,加上Price内部字段是全大写命名,后续即使识别到price字段,也会出现内部属性匹配失败的问题
修复方案
按以下步骤逐一调整即可解决:
修正实体类注解配置
- 删除Product类里手动编写的无参构造
public Product() {},放开@NoArgsConstructor的注释,不要混合使用Lombok构造器注解和手动编写的同类型构造器,避免Lombok生成方法异常 - 把Price类里标注在
GST字段上的@JsonIgnoreProperties(ignoreUnknown=true)挪到Price类的声明上,和@Embeddable、@Data等注解放在同一层级 - 给嵌套字段显式加上
@JsonProperty注解指定JSON映射关系,避免字段名大小写导致的匹配失败 - 如果使用SpringBoot 3.x及以上版本,请把所有
javax.persistence包的导入替换为jakarta.persistence,否则后续JPA持久化层会报错
修正后的Product类代码:
package com.shashikanth.curd.eg.entity; import javax.persistence.Embedded; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import com.fasterxml.jackson.annotation.JsonProperty; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @Data @AllArgsConstructor @NoArgsConstructor @Entity public class Product { @Id @GeneratedValue private int id; private String name; private int quantity; @Embedded @JsonProperty("price") private Price price; }修正后的Price类代码:
package com.shashikanth.curd.eg.entity; import javax.persistence.Embeddable; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @Data @AllArgsConstructor @NoArgsConstructor @Embeddable @JsonIgnoreProperties(ignoreUnknown = true) public class Price { @JsonProperty("GST") private double GST; @JsonProperty("MRP") private double MRP; }- 删除Product类里手动编写的无参构造
替换手动创建的ObjectMapper为Spring容器托管实例
不要在启动类中自己new ObjectMapper,直接注入SpringBoot自动配置好的ObjectMapper实例,这个实例已经预配置了所有必要的序列化规则、兼容模块,不会出现自定义类型识别问题。
修正后的启动类核心代码:package com.shashikanth.curd.eg; import java.io.InputStream; import java.util.List; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Bean; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; import com.shashikanth.curd.eg.entity.Product; import com.shashikanth.curd.eg.service.ProductService; @SpringBootApplication public class CurdingApplication { public static void main(String[] args) { SpringApplication.run(CurdingApplication.class, args); } @Bean CommandLineRunner runner(ProductService productService, ObjectMapper objectMapper) { return args -> { TypeReference<List<Product>> typeReference = new TypeReference<>(){}; InputStream inputStream = TypeReference.class.getResourceAsStream("/json/users.json"); try { List<Product> products = objectMapper.readValue(inputStream,typeReference); productService.saveProducts(products); System.out.println("Products Saved!"); } catch (Exception e){ System.out.println("Unable to save products: " + e.getMessage()); e.printStackTrace(); } }; } }检查开发环境配置
确认IDE已经安装Lombok插件并开启了注解处理开关,否则Lombok注解不会在编译期生效,会导致getter/setter缺失、构造器缺失等一系列问题。校验JSON文件格式
贴出的JSON片段开头缺失数组起始符号[,请确认实际的JSON文件最外层是完整的数组结构,没有语法错误。
内容的提问来源于stack exchange,提问作者shashikanth
相关产品推荐
相关产品推荐

