Jackson反序列化嵌套对象内空数组触发NullPointerException问题咨询
Jackson反序列化嵌套空数组触发NullPointerException解决方案
问题根因
该异常不是Jackson依赖库本身的原生缺陷,核心触发原因是JPA双向实体关联的@JsonIgnoreProperties配置不完整,导致反序列化上下文传递时集合元素反序列化器(valueDes)丢失:
- 实体存在两组双向关联:
Person <-> MyMail、Person <-> Deploy Person <-> Deploy的双向关联两侧都配置了@JsonIgnoreProperties打断循环引用,但Person <-> MyMail的关联中,仅Person侧的mailList字段配置了@JsonIgnoreProperties,MyMail侧的personWithMail字段未配置对应忽略规则- 当反序列化路径走到
deploys数组元素 -> Deploy.employee(Person类型) -> Person.mailList时,Jackson处理循环引用过滤的递归逻辑出现上下文断层,无法获取List<MyMail>的元素反序列化器实例,执行到valueDes.getObjectIdReader()判断时直接触发空指针 - 外层
aPersonOutsideDeploy下的mailList空数组不触发错误,是因为该路径未进入循环引用过滤的递归分支,反序列化器上下文完整。
最优修复方案
不需要自定义反序列化器做特殊处理,从根源解决问题只需要两步:
- 补全双向关联的@JsonIgnoreProperties配置,在MyMail类的personWithMail字段上添加对应注解,完整打断循环引用路径:
@Entity public class MyMail{ //... @ManyToOne(fetch = FetchType.EAGER, optional = true) @JsonIgnoreProperties(value = "mailList") // 新增该行,对应Person类中的mailList属性 private Person personWithMail; }
- 如果你当前使用的Jackson版本低于2.9.10,升级到2.9.x最新稳定版或2.10+版本,老版本在循环引用场景下的集合反序列化上下文传递存在已知缺陷,未对空数组场景下的valueDes做判空兜底,新版本已修复该类问题。
临时规避方案说明
你当前实现的自定义反序列化器(空数组直接返回空列表)仅能临时绕过空指针问题,没有解决循环引用配置缺失的本质问题:当mailList字段传入非空数组时,依然会触发双向关联的无限递归问题,不建议作为长期方案使用。
如果暂时无法修改注解配置,也可以通过给实体类的集合字段提前初始化空实例的方式规避触发点:
// 在Person实体类中给mailList赋初始空值 @OneToMany(fetch = FetchType.LAZY,mappedBy = "personWithMail") @JsonIgnoreProperties(value = "personWithMail") private List<MyMail> mailList = new ArrayList<>();
内容的提问来源于stack exchange,提问作者M4HdYaR
相关产品推荐
相关产品推荐

