一、遇到的问题:
在dao层实现一个根据仓库名称查询用户id时出现了问题,若查询仓库存在时则无什么大问题,但当查询仓库不存在时则报了一个空指针异常,这一点是很奇怪的,因为我dao层接收的是Integer类型,按道理说应该也是接受到一个null。
二、以下是该方法各层的代码:
dao
//根据仓库名称查询商户ID
Integer getBankerIdByWarehouse(@Param("warehouse") String warehouse);
xml
<select id="getBankerIdByWarehouse" resultType="java.lang.Integer" >
select id from yx_banker where name = #{warehouse}
</select>
service
Integer getBankerIdByWarehouse(String warehouse);
serviceImpl
/**
* 测试接口
* 根据供应商名称查询供应商ID
* @param warehouse
* @return
*/
@Override
public Integer getBankerIdByWarehouse(String warehouse) {
Integer id = 0;
try{
id = bankerDao.getBankerIdByWarehouse(warehouse);
}catch (Throwable e){
log.info("出问题了");
}
return id;
}
controller
@GetMapping("/getBankerIdByWarehouse")
public CommonResult getBankerIdByWarehouse(String warehouse){
System.out.println("getBankerIdByWarehouse============>"+warehouse);
Integer id = bankerInfoService.getBankerIdByWarehouse(warehouse);
if(id > 0){
return CommonResult.success(id,"查询成功");
}
return CommonResult.failed("查询失败");
}
三、操作
-
首先使用存在的仓库名称进行查询,用postman进行测试,结果如下:
{ "code": 200, "message": "查询成功", "data": 3 } -
使用不存在的仓库名称进行查询,其结果如下
{ "code": 500, "message": "系统异常", "data": null }同时在控制台出现的错误信息如下:
四、出现的问题
根据出现的报错信息,可以看到是一个空指针的异常,但是我在Dao层和Service层都使用了Integer类型进行接收,并且在ServiceImpl层中也使用了try catch进行异常捕捉,按道理说当id为null时就应该获得0这个值,但是依旧为空,这让身为菜鸟的我感到很奇怪。
五、解决方法
首先我在网上去查询了一些解决方法,但一来是因为关于空指针的问题很多,二来是当时我没有意识到真正的问题,所以最后在查询了10分钟左右后就去向我的组长进行询问,最后发现了问题的由来。
六、解决过程
我先给组长简单讲解了一下问题,并给他看了一下这个方法从xml到controller层的实现,然后再帮我看了一下报错信息,最后锁定在了controller层
at com.qmyx.store.controller.BankerInfoController.getBankerIdByWarehouse(BankerInfoController.java:29)
出现问题的地方就是controller层,但是由于自己习惯性的忽略(简单的扫了一下controller层)就感觉没问题。先看一下controller层这个方法没有修改前的样子:
@GetMapping("/getBankerIdByWarehouse")
public CommonResult getBankerIdByWarehouse(String warehouse){
System.out.println("getBankerIdByWarehouse============>"+warehouse);
Integer id = bankerInfoService.getBankerIdByWarehouse(warehouse);
if(id > 0){
return CommonResult.success(id,"查询成功");
}
return CommonResult.failed("查询失败");
}
出现的浅显问题是空指针异常,但实际上是类型转换异常,因为id是Integer类型,所以在if语句中会自动拆箱,以便于与int类型进行比较,但是问题是当id原来为null时,如果使用自动拆箱,就会出现错误,因为Integer类型的引用为null时并不是我想的那样会被拆箱成为0,而是拆箱失败,因为Integer id = null 就意味着id没有指向的实际对象,没有对象又如何能拆箱呢。最后组长建议我在if判断中加入一个id是否为null的判断,经过测试后得到了很好的解决,代码如下:
@GetMapping("/getBankerIdByWarehouse")
public CommonResult getBankerIdByWarehouse(String warehouse){
System.out.println("getBankerIdByWarehouse============>"+warehouse);
Integer id = bankerInfoService.getBankerIdByWarehouse(warehouse);
if(null != id && id > 0){
return CommonResult.success(id,"查询成功");
}
return CommonResult.failed("查询失败");
}
{
"code": 500,
"message": "查询失败",
"data": null
}
postman测试结果和预期的一样,后台业务报错信息,说明解决了此问题
七、扩展
组长在给我解决办法后我尝试解决,并且成功,但是他强调了为空的判断要放在前面,所以我想尝试放在后面进行测试一下,进行测试后不出所料,程序还是报错了,依旧是空指针异常,这是因为先判断 id > 0 其实就意味着进行自动拆箱了,所以会出现一开始的问题,因此需要将是否为null的判断放在前面。