HTTP Status 500 – Internal Server Error
Request processing failed; nested exception is java.lang.IllegalStateException: Optional long parameter ‘goodsId’ is present but cannot be translated into a null value due to being declared as a primitive type. Consider declaring it as object wrapper for the corresponding primitive type.
今天开发项目的删除商品功能时,我碰到了上面这个问题,本来我打算按照提示把long类型换成Long类型,但是后来我发现并不是这里影响的。
首先我们来看一下Dao层的代码:
/**
* 删除商品
* @param goodsId 商品id
* @return ...
*/
int deleteGoods(long goodsId);
/**
* 通过商品Id查询商品
* @param goodsId 商品Id
* @return 查询的结果
*/
Goods findByGoodsId(long goodsId);
然后来看一下mapper文件里面的映射:
<insert id="insertGoods" parameterType="com.zhongruan.bean.Goods">
insert into goods(userId,typeId,goodsName,goodsContent,goodsNumber,goodsOrginalPrice,goodsNowPrice,goodsPopularity,goodsStatus,goodsImage)
values (#{userId},#{typeId},#{goodsName},#{goodsContent},#{goodsNumber},#{goodsOrginalPrice},#{goodsNowPrice},#{goodsPopularity},#{goodsStatus},#{goodsImage})
</insert>
<delete id="deleteGoods" parameterType="java.lang.Long">
delete from goods where goodsId=#{goodsId}
</delete>
接下来是Service层的代码:
/**
* 下架商品
* @param goodsId 商品Id
* @return 下架信息
*/
Result subGoods(long goodsId);
Service层的实现:
这里一定要注意数据库的主外键关系,由于我的商品ID是其他三个表(订单、收藏、发布)的外键,所以在删除商品前要先把包含这个商品的记录删掉,否则就会报错,这个一定要注意。
@Override
public Result subGoods(long goodsId) {
Goods goods = goodsDao.findByGoodsId(goodsId);
//首先删除商品留言
List<Message> messages = messageDao.findByGoodsId(goodsId);
if(messages.size() > 0){
for (Message message : messages) {
messageDao.deleteMessage(message.getMessageId());
}
}
//删除用户收藏
List<Enshrine> enshrines = enshrineDao.findByGoodsId(goodsId);
if(enshrines.size() > 0){
for (Enshrine enshrine: enshrines
) {
enshrineDao.deleteEnshrine(enshrine.getEnshrineId());
}
}
//删除商品订单
List<Purchase> purchases = purchaseDao.findPurchasesByGoodsId(goodsId);
if(purchases.size() > 0){
for (Purchase purchase: purchases
) {
purchaseDao.deletePurchase(purchase.getPurchaseId());
}
}
//删除商品
goodsDao.deleteGoods(goodsId);
return new Result("下架成功",goods);
}
最后是Controller层的代码:
@RequestMapping(value = "subGoods")
public String subGoods(long goodsId,Model model){
goodsService.subGoods(goodsId);
Result result = goodsService.findByGoodsPopularityAsc();
model.addAttribute("goodsList",result.getData());
return "goods-list";
}
看到这里,我发现逻辑根本没有错误,那到底是什么原因呢?我仔细思考了一下有两种可能:
- 路径的映射错误
- 参数名拼写错误
带着这样的思考,我首先检查了一下路径,发现并没有问题,然后我接着看JSP页面里面的参数名,最后终于被我发现了,原来是把goodsId写成了id,真的是粗心大意,于是goodsId这个参数就没有被赋值,所以为空,但是它是long类型的,所以浏览器建议把long改成Long类型的,但是即使不报500错误了,你也删不掉这个商品,所以问题的根源不是类型错误,而是传值的参数错了
值得一提的是: 我这里还有一个id参数,所以系统没有报找不到参数的错误,看吧,有些玄学bug就是这么来的。
修改之后完美运行
这里我想强调的是,有的时候项目报错不一定是逻辑错误,也不一定和IDE报出的错误完全对应,所以平时写代码的时候一定要细心,尤其是在写没有自动补全的函数名/参数名时。