有时候会用deprecated注解表示该字段已经废弃或即将废弃,protostuff序列化会直接忽略这个字段。
[TOC]
背景
我们的业务数据在搜索阶段和填单阶段出现了不一致, 少了drawbackMapping字段,导致用户看到的退改规则不一致。
数据DIFF如下:

代码如下:

排查思路
范围缩小
首先,drawbackMapping字段存在已久,排除最有可能原因:Jar包版本不一致导致字段缺失。
然后依次检查上游系统链路日志,定位到是在我们的上游交易系统中,丢失了drawbackMapping字段。
上游交易系统链路比较长,排查日志和代码也比较麻烦。
此时发现这个字段与其它字段唯一的区别就是有一个@Deprecated注解,开始猜测最有可能的原因:序列化和反序列化。
猜测1:Json序列化
交易系统用的Jackson工具,梳理一下Jackson序列化丢失字段的常见原因:
getter方法和setter方法问题- 字段属性为
private且getter方法和setter缺失 - 使用lombok注解自动生成
getter和setter方法,属性命名首字母小写第二个字母大写。例如aBcd,lombok生成getABcd方法,jackson截取ABcd后会将连续大写字母转成小写最终变成abcd而不是aBcd - 使用
@JsonIgnore注解忽略字段
- 字段属性为
猜测2:Protostuff序列化
继续排查其它序列化方式,发现交易系统部分流程使用了protostuff序列化
protostuff竟然会忽略@Deprecated注解字段!
来自 Protostuff官方文档:
Java中的deprecated注解官方解释
来自 Java8官方文档:
A program element annotated @Deprecated is one that programmers are discouraged from using, typically because it is dangerous, or because a better alternative exists. Compilers warn when a deprecated program element is used or overridden in non-deprecated code.
后续版本的解释都差不多。
总结
用@Deprecated的初衷是表明该字段不建议被使用,如果还没有完全废弃的话不推荐使用。
以前就踩过protostuff的一个坑,在类里面新增属性没有加在最末尾,结果上游系统用了protostuff,导致反序列化失败。
在使用protostuff的时候,应该对下游系统负责。
