一、问题发现
生产上线某功能,撇去该功能业务逻辑不说,该功能有一个接口,就是将查找出来的记录,更新某个字段的值后重新保存到表里。这个接口之前在service层使用XxxRepository查询数据,没有手写sql,保存时也是直接将整个查询到的XxxEntity也是直接XxxRepository.save(XxxEntity)。但由于功能需要,service层全部重写了,查询数据改成了jdbcTemplate.query(sql,param,new BeanPropertyRowMapper<>(XxxEntity.class))查询到一个List,保存时使用XxxRepository.saveAll(list)。
实体类类似于:
@Column("aaa_bbb_ccc")
private String aaabbbCcc; // 不规范驼峰命名的
@Column("ddd_eee")
private String ddEee; // 驼峰和_的单词不对应的
由于这些对业务没有多大得关联影响,上线测试没有发现,直到业务上面的字段出现了不会为空但为空的情况,也没有想到这上面来,毕竟这些字段没有关联,排查过程中才发现的这些字段本来是有的,当时却没了。排查了代码,一开始也没有怀疑是最近上线的问题,因为代码写的逻辑都找不出毛病,但统计发现确实是最近上线之后,这些不规范字段为空的情况大大增加了。最后大佬一看,指出了问题的原因。
二、总结
因为粗心大意,没有注意到这些不规范命名的字段没有映射到值,使得List中的数据发生了意料之外的变化,又没有使用jdbc去更新单个字段,而是对整个Entity进行了更新,导致没映射到值得字段都变成了空。
- 对于命名不规范的字段一定要提起十二分精神,不可粗心大意;
- 在查询数据时,手写的sql不要使用select
*
而是将*
展开为各个字段(但是,这样又需要注意在增删字段时要加上),所以,字段命名规范很重要; - 对于对字段值的更新,不要去更新全量的字段,涉及哪些字段,就去update哪些字段,不可以偷懒;
- 最后,数据的恢复真的全都依靠了接口日志,所以接口日志真的很重要,接口的调用返回最好要保存到交互记录表里。