前言
某一天,老大把小编叫到了一个小黑屋(不要想多了)
老大:鉴于你最近良好的表现…
小编:公司是要给我涨工资吗?(无限yy中)
老大:哦,不。是让你再帮忙维护一个项目。
小编:emmmmmmm。(默默的走出了小黑屋)
说时迟那时快,只见小编刚刚走出小黑屋,顺手拿起了手机看一眼(日常划水)。企业微信里老大头像上瞬间亮起了一个小红点。。。。。“这个是项目地址和文档地址,回去看一下”。
what XXXX。
小编只能默默地回到了工位上,开始静静的搬砖。
很快,项目下载完了,当打开项目的时候,小编被那一行行if else拼接起来的sql深深的吸引住了,大声感叹道,此物只应天上有,赶紧回天上去吧。
之后小编就开始了程序员接项目的最终奥义,“重构“(这里说的简单,其实是和老大聊了好长时间才决定的重构,因为突然了解到要长期维护——……————)。
首先就从那一坨坨sql开始,因为本身项目不大,不复杂,也不需要这种复杂的sql,很影响阅读,而且现在国内公司大多都用mybatis,普及率要比hibernate高很多,为了方便后人维护,小编第一步就是将hibernate替换为mybatis。
正文开始啦
几天后,小编刚刚把整个项目熟悉了一遍。就开始了大刀阔斧,用mybatis重写了一个新增数据的功能。写完之后,通过单元测试发现没问题,但是(凡事就怕但是),小编目前只改了这个新增,有几个更新sql还是用的原有的hibernate代码,小编没事闲的就试试原有的更新数据接口,突然,报了NullPointException,而且还不是业务代码,是hibernate源码里报的。
小编的脑海里这时突然就想起了程序员界的三个词。“没动过”,“没改过”,“不知道”。
但是小编又一想,我怎么辜负领导的信任(_^_XXXX),于是就开始了追寻BUG之路。
废话不多说,按惯例先上BUG。
是不是一看堆栈信息聪明的大家就猜出来是什么问题了?别急,大家和小编一起看一看源码,对先贤致敬。
- 首先我们从hibernate执行sql开始
- 我们往下走,发现这里面竟然还有一个事物注解,将当前sql加入到事物中,当sql报错时进行回滚。当然这个我们暂时先不看,和这个问题没什么关系。
- 接下来我们一路往下走
- 最后小编找到报错的最终地点是这里,hibernate的乐观锁,更新版本号的功能,见下面两张图,源码中显示,hibernate在更新数据时,直接拿版本号做了+1。并没有考虑是不是为空。由于小编将新增数据改为了用mybatis,mybatis是没有自带乐观锁这个东西的,所以小编就忽略了版本号这个字段,当新增数据时这个字段直接默认成了null,导致了这个错误。
最后,小编将新增数据时,增加了默认版本号,解决了这个问题。大家在修改代码时一定要注意对其他代码的影响。
如有幸被转载请注明出处,谢谢。如有不对的地方,请大家指出,小编查实后将会对文章进行更正。