淘先锋技术网

首页 1 2 3 4 5 6 7

问题现象:

        今天在项目中遇到一个mybatis的报错:

        org.apache.ibatis.ognl.OgnlException: source is null for getProperty(null, "staffId")

        这是我之前从未遇到过的问题,挺有意思的,所以特此记录一下。


问题分析:

       根据报错日志来看,一开始我以为它说的是:

        在执行mybatis的sql时,参数 staffId 的值是null,所以报错了!

但是细想之下发现不对劲,如果 staffId  是null ,而数据库是非空字段的话,它的报错不应该是现在这个日志,而应该是:

    Column 'staff_id' cannot be null

        于是我只好把项目debug起来,看看到底是什么问题导致的。

        最终定位到了出现问题的dao操作:

         通过debug发现原来是因为传入的参数 xxxEntity 是null,而mybatis提供的updateById等基本的dao操作方法,是不支持传参为null的,因此导致了文章开头的报错!

        其实,如果能看清楚或者理解清楚报错信息的话,也不难知道问题所在:

    source is null

         意思是资源对象(参数 xxxEntity )为null,因此获取null对象的staffId时,也是null。

        既然知道问题所在,那解决问题还不手到擒来么!


拓展:

        疑问:资源对象(参数 xxxEntity )为null,那为什么报错信息偏偏指定到 staffId 参数呢?

        回答:其实这是和资源对象的序列化有一定的关系,因为 staffId 是这个实体对象的第一个字段,因此在使用get方法获取这个字段值的时候就已经发现有问题,从而直接抛出报错信息了;而没有再往下获取其他字段的值,上图可能会更容易理解一些:

        PS:可以看出 xxxEntity 实体对象中第一个字段就是 staffId。


 解决方法:

        解决方法其实非常简单,就是给参数对象加上判空逻辑,再去执行dao操作,如下:

总结:

        这个报错日志其实出现的概率非常低,因为我们执行dao操作时,常常是通过dto对象接收前端传入的请求体,而这个dto对象基本都不会是直接传null对象,反倒是对象的某个字段值可能是null值;而且,基本上都会对dto对象的必填字段进行参数检验,综合因素导致这个报错日志其实出现的概率非常低,不过还是要注意一下。