定时任务中将redis数据存入数据库相关问题

news2024/11/17 10:55:28

我的GitHub: Powerveil · GitHub
我的Gitee: Powercs12 (powercs12) - Gitee.com
皮卡丘每天学Java

觉得昨天晚上只是分析和解决问题,很多人可能不知道出bug的场景,今天决定重现bug,让代码改回错误代码,重现看到一大串异常的情形[手动狗头]

问题出处:

B站:https://www.bilibili.com/video/BV1hq4y1F7zk?p=83

9:37时运行时报错,NullPointerException

异常信息

2023-01-20 11:27:40.009 ERROR 15584 --- [   scheduling-1] o.s.s.s.TaskUtils$LoggingErrorHandler    : Unexpected error occurred in scheduled task

org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.exceptions.PersistenceException: 
### Error updating database.  Cause: java.lang.NullPointerException
### The error may exist in com/power/mapper/ArticleMapper.java (best guess)
### The error may involve com.power.mapper.ArticleMapper.updateById
### The error occurred while executing an update
### Cause: java.lang.NullPointerException
    at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:96) ~[mybatis-spring-2.0.6.jar:2.0.6]
    at com.baomidou.mybatisplus.extension.toolkit.SqlHelper.executeBatch(SqlHelper.java:179) ~[mybatis-plus-extension-3.4.3.jar:3.4.3]
    at com.baomidou.mybatisplus.extension.toolkit.SqlHelper.executeBatch(SqlHelper.java:204) ~[mybatis-plus-extension-3.4.3.jar:3.4.3]
    at com.baomidou.mybatisplus.extension.service.impl.ServiceImpl.executeBatch(ServiceImpl.java:248) ~[mybatis-plus-extension-3.4.3.jar:3.4.3]
    at com.baomidou.mybatisplus.extension.service.impl.ServiceImpl.updateBatchById(ServiceImpl.java:200) ~[mybatis-plus-extension-3.4.3.jar:3.4.3]
    at com.baomidou.mybatisplus.extension.service.IService.updateBatchById(IService.java:177) ~[mybatis-plus-extension-3.4.3.jar:3.4.3]
    at com.baomidou.mybatisplus.extension.service.IService$$FastClassBySpringCGLIB$$f8525d18.invoke(<generated>) ~[mybatis-plus-extension-3.4.3.jar:3.4.3]
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218) ~[spring-core-5.3.7.jar:5.3.7]
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:779) ~[spring-aop-5.3.7.jar:5.3.7]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-5.3.7.jar:5.3.7]
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:750) ~[spring-aop-5.3.7.jar:5.3.7]
    at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:123) ~[spring-tx-5.3.7.jar:5.3.7]
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:388) ~[spring-tx-5.3.7.jar:5.3.7]
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119) ~[spring-tx-5.3.7.jar:5.3.7]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.7.jar:5.3.7]
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:750) ~[spring-aop-5.3.7.jar:5.3.7]
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:692) ~[spring-aop-5.3.7.jar:5.3.7]
    at com.power.service.impl.ArticleServiceImpl$$EnhancerBySpringCGLIB$$4ebc6fef.updateBatchById(<generated>) ~[classes/:na]
    at com.power.job.UpdateViewCountJob.updateViewCount(UpdateViewCountJob.java:74) ~[classes/:na]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_321]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_321]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_321]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_321]
    at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:84) ~[spring-context-5.3.7.jar:5.3.7]
    at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) ~[spring-context-5.3.7.jar:5.3.7]
    at org.springframework.scheduling.concurrent.ReschedulingRunnable.run(ReschedulingRunnable.java:95) [spring-context-5.3.7.jar:5.3.7]
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [na:1.8.0_321]
    at java.util.concurrent.FutureTask.run(FutureTask.java:266) [na:1.8.0_321]
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180) [na:1.8.0_321]
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293) [na:1.8.0_321]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_321]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_321]
    at java.lang.Thread.run(Thread.java:750) [na:1.8.0_321]
Caused by: org.apache.ibatis.exceptions.PersistenceException: 
### Error updating database.  Cause: java.lang.NullPointerException
### The error may exist in com/power/mapper/ArticleMapper.java (best guess)
### The error may involve com.power.mapper.ArticleMapper.updateById
### The error occurred while executing an update
### Cause: java.lang.NullPointerException
    at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30) ~[mybatis-3.5.7.jar:3.5.7]
    at org.apache.ibatis.session.defaults.DefaultSqlSession.update(DefaultSqlSession.java:196) ~[mybatis-3.5.7.jar:3.5.7]
    at com.baomidou.mybatisplus.extension.service.impl.ServiceImpl.lambda$updateBatchById$3(ServiceImpl.java:203) ~[mybatis-plus-extension-3.4.3.jar:3.4.3]
    at com.baomidou.mybatisplus.extension.toolkit.SqlHelper.lambda$executeBatch$1(SqlHelper.java:208) ~[mybatis-plus-extension-3.4.3.jar:3.4.3]
    at com.baomidou.mybatisplus.extension.toolkit.SqlHelper.executeBatch(SqlHelper.java:169) ~[mybatis-plus-extension-3.4.3.jar:3.4.3]
    ... 31 common frames omitted
Caused by: java.lang.NullPointerException: null
    at com.power.utils.SecurityUtils.getLoginUser(SecurityUtils.java:24) ~[classes/:na]
    at com.power.utils.SecurityUtils.getUserId(SecurityUtils.java:49) ~[classes/:na]
    at com.power.handler.mybatisplus.MyMetaObjectHandler.updateFill(MyMetaObjectHandler.java:41) ~[classes/:na]
    at com.baomidou.mybatisplus.core.MybatisParameterHandler.lambda$updateFill$1(MybatisParameterHandler.java:154) ~[mybatis-plus-core-3.4.3.jar:3.4.3]
    at java.util.Optional.ifPresent(Optional.java:159) ~[na:1.8.0_321]
    at com.baomidou.mybatisplus.core.MybatisParameterHandler.updateFill(MybatisParameterHandler.java:152) ~[mybatis-plus-core-3.4.3.jar:3.4.3]
    at com.baomidou.mybatisplus.core.MybatisParameterHandler.process(MybatisParameterHandler.java:115) ~[mybatis-plus-core-3.4.3.jar:3.4.3]
    at com.baomidou.mybatisplus.core.MybatisParameterHandler.processParameter(MybatisParameterHandler.java:81) ~[mybatis-plus-core-3.4.3.jar:3.4.3]
    at com.baomidou.mybatisplus.core.MybatisParameterHandler.<init>(MybatisParameterHandler.java:64) ~[mybatis-plus-core-3.4.3.jar:3.4.3]
    at com.baomidou.mybatisplus.core.MybatisXMLLanguageDriver.createParameterHandler(MybatisXMLLanguageDriver.java:45) ~[mybatis-plus-core-3.4.3.jar:3.4.3]
    at org.apache.ibatis.session.Configuration.newParameterHandler(Configuration.java:645) ~[mybatis-3.5.7.jar:3.5.7]
    at org.apache.ibatis.executor.statement.BaseStatementHandler.<init>(BaseStatementHandler.java:69) ~[mybatis-3.5.7.jar:3.5.7]
    at org.apache.ibatis.executor.statement.PreparedStatementHandler.<init>(PreparedStatementHandler.java:41) ~[mybatis-3.5.7.jar:3.5.7]
    at org.apache.ibatis.executor.statement.RoutingStatementHandler.<init>(RoutingStatementHandler.java:46) ~[mybatis-3.5.7.jar:3.5.7]
    at org.apache.ibatis.session.Configuration.newStatementHandler(Configuration.java:658) ~[mybatis-3.5.7.jar:3.5.7]
    at org.apache.ibatis.executor.BatchExecutor.doUpdate(BatchExecutor.java:57) ~[mybatis-3.5.7.jar:3.5.7]
    at org.apache.ibatis.executor.BaseExecutor.update(BaseExecutor.java:117) ~[mybatis-3.5.7.jar:3.5.7]
    at org.apache.ibatis.executor.CachingExecutor.update(CachingExecutor.java:76) ~[mybatis-3.5.7.jar:3.5.7]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_321]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_321]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_321]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_321]
    at org.apache.ibatis.plugin.Invocation.proceed(Invocation.java:49) ~[mybatis-3.5.7.jar:3.5.7]
    at com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor.intercept(MybatisPlusInterceptor.java:106) ~[mybatis-plus-extension-3.4.3.jar:3.4.3]
    at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:62) ~[mybatis-3.5.7.jar:3.5.7]
    at com.sun.proxy.$Proxy122.update(Unknown Source) ~[na:na]
    at org.apache.ibatis.session.defaults.DefaultSqlSession.update(DefaultSqlSession.java:194) ~[mybatis-3.5.7.jar:3.5.7]
    ... 34 common frames omitted

这是定时任务执行的方法。

该定时任务的目的是将文章的浏览量从Redis中更新到Mysql中的文章表中
redisCache自定义的一个类,封装了RedisTemplate的一些方法
viewCountMap的key是文章id,value是文章的viewCount

下面程序运行时定时任务多打印一句话,这是昨天的图片,不想换了。

相关知识:Mybatis Plus、Spring Security、Redis、Mysql

本质原因:我们自己将Article字段的update字段做了自动填充导致自动填充时无法获取当前用户(程序刚启动时没有用户登录)。

为了代码更完善一点,我写了自动填充,但是这也导致了一个问题,在执行updateBatchById(articles)的时候,create相关字段会自动填充,看一下自动填充的具体代码。

getUserId()这个方法

看到这里大家可能就明白了,此时我们还没有登录,获取getLoginUser()就会出错,具体是jwt检验token的时候没有将当前用户信息存入存入SecurityContextHolder。其实也没必要存,因为我们做的是定时任务,不需要什么用户信息。

没有执行SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);

所以Authentication没有我们想要的值。没看过源码,不知道有没有默认值(没有默认值,后面看异常出现的位置可以推测)

下图两个位置出现空指针异常(如果Authentication有默认值,1出报异常,没有默认值,2出报异常)

异常信息的下面

上图可见,1处报异常

所以上面讨论的Authentication没有默认值。

解决方案1:去掉Article部分字段的自动填充

测试结果:

解决方案2(推荐):

从根源修改:

保留自动填充,因为这里没有牵扯到用户,所以自动填充的时候要判断是否填充

public class SecurityUtils {
    /**
     * 获取用户
     **/
    public static LoginUser getLoginUser() {
        if (!Objects.isNull(getAuthentication())) {
            return (LoginUser) getAuthentication().getPrincipal();
        }
        return null;
    }

    /**
     * 获取Authentication
     */
    public static Authentication getAuthentication() {
        return SecurityContextHolder.getContext().getAuthentication();
    }

    public static Boolean isAdmin() {
        if (!Objects.isNull(getLoginUser())) {
            Long id = getLoginUser().getUser().getId();
            return SystemConstants.USER_ADMIN_ID.equals(id);
        }
        return false;
    }

    public static Long getUserId() {
        if (!Objects.isNull(getLoginUser())) {
            return getLoginUser().getUser().getId();
        }
        return null;
    }

测试结果:

因为刚才着急测试结果,次数多了几次。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/173266.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

科研快报|PacBio 16S全长测序探究游离唾液微生物群失调在牙周病中的潜在作用

背景介绍唾液是口腔中最重要的介质。唾液中游离细菌的生态失调可能与牙周病的发生、发展、预后和复发有关&#xff0c;但这种潜在的关系尚不清楚。本研究的目的是探讨游离唾液微生物群在不同牙周状态下的潜在作用&#xff0c;它们对非手术牙周治疗的反应&#xff0c;以及治疗后…

年后旺季,服装实体店如何利用微信做新款宣传?

每年过完大年开工后&#xff0c;我们服装的旺季就来临了&#xff0c;对于很多服装店铺来说&#xff0c;无疑是一个必须把握的大好机会。就拿这几天的天气来说&#xff0c;广东最高温度达到了26度&#xff0c;很多人又把自己春夏的衣服拿出来了&#xff0c;而年后气温必然回暖&a…

Swin Transformer代码实战篇

&#x1f34a;作者简介&#xff1a;秃头小苏&#xff0c;致力于用最通俗的语言描述问题 &#x1f34a;往期回顾&#xff1a;CV攻城狮入门VIT(vision transformer)之旅——近年超火的Transformer你再不了解就晚了&#xff01; CV攻城狮入门VIT(vision transformer)之旅——VIT原…

列表元素 有序列表 无序列表 定义列表 ol: ul: dl: dd: dt:

目录列表元素有序列表无序列表定义列表列表元素 有序列表 ol: ordered list 表示整个列表 li: list item 表示单个列表&#xff0c;列表的子元素 reversed: 导则 列表的写法&#xff1a; 但实际开发中一般不用type来设置列表的序&#xff0c;而是用css 把大象装冰箱分几步…

SpringBoot 项目

不得不佩服 Spring Boot 的生态如此强大&#xff0c;今天我给大家推荐几款 Gitee 上优秀的后台开源版本的管理系统&#xff0c;小伙伴们再也不用从头到尾撸一个项目了&#xff0c;简直就是接私活&#xff0c;挣钱的利器啊。SmartAdmin我们开源一套漂亮的代码和一套整洁的代码规…

2.4、进程通信

整体框架 1、什么是进程通信&#xff1f; 顾名思义&#xff0c;进程通信就是指进程之间的信息交换。 进程是分配系统资源的单位&#xff08;包括内存地址空间)&#xff0c; 因此各进程\color{red}各进程各进程拥有的内存地址空间相互独立\color{red}内存地址空间相互独立内存…

知识分享-商业数据分析业务全流程

&#x1f935;‍♂️ 个人主页&#xff1a;艾派森的个人主页 ✍&#x1f3fb;作者简介&#xff1a;Python学习者 &#x1f40b; 希望大家多多支持&#xff0c;我们一起进步&#xff01;&#x1f604; 如果文章对你有帮助的话&#xff0c; 欢迎评论 &#x1f4ac;点赞&#x1f4…

力扣sql简单篇练习(二)

力扣sql简单篇练习(二) 1 从不订购的客户 1.1 题目内容 1.1.1 基本题目信息 1.1.2 示例输入输出 1.2 示例sql语句 # 一个人也是有可能下多个订单的 SELECT name Customers FROM Customers WHERE id not in(SELECT distinct Customerid FROM Orders)1.3 运行截图 2 删除重…

【LINUX修行之路】工具篇——Vim的使用及配置

&#x1f37f;本节主题&#xff1a;vim的使用 &#x1f388;推荐阅读&#xff1a;回溯算法 、C入门&#xff08;上篇&#xff09; &#x1f495;我的主页&#xff1a;蓝色学者的主页 文章目录一、前言二、文本编辑器和IDE三、选择vim的理由四、vim操作模式4.1普通模式(command …

springboot项目实现腾讯云的短信验证

前言&#xff1a;可以先去看下腾讯云开通短息服务需要哪些信息。我这里使用自己很久之前申请过的公众号&#xff0c;其他的比如网站&#xff0c;小程序啥的也没有&#xff0c;哈哈哈~。 腾讯云地址&#xff1a; https://console.cloud.tencent.com/smsv2/csms-sign/create接下…

非父子组件的通信

在开发中&#xff0c;我们构建了组件树之后&#xff0c;除了父子组件之间的通信之外&#xff0c;还会有非父子组件之间的通信。这里我们主要讲两种方式&#xff1a; Provide/Inject&#xff1b;全局事件总线&#xff1b; 1、Provide和Inject Provide/Inject用于非父子组件之间…

什么是OAuth2

2.3 什么是OAuth2 2.3.1 OAuth2认证流程 在前边我们提到微信扫码认证&#xff0c;这是一种第三方认证的方式&#xff0c;这种认证方式是基于OAuth2协议实现&#xff0c; OAUTH协议为用户资源的授权提供了一个安全的、开放而又简易的标准。同时&#xff0c;任何第三方都可以使…

离散数学-图论-图的基本概念(11)

图的基本概念 1 图 1.1 图的定义 定义1&#xff1a; 一个无向图G是一个有序的二元组<V,E>&#xff0c;其中 &#xff08;1&#xff09;V是一个非空有穷集&#xff0c;称为顶点集&#xff0c;其元素称为顶点或结点。 &#xff08;2&#xff09;E是无序积V&V的有穷多…

什么是安卓版 UI 业务包 SDK?如何接入?

涂鸦 Android 业务包是指包含业务逻辑和 UI 界面的涂鸦垂直业务模块&#xff0c;旨在为基于涂鸦智能生活 SDK 开发的应用提供快速的一站式接入涂鸦业务模块的能力。 概述 目前提供的业务包种类繁多&#xff0c;例如&#xff1a; H5 商城设备配网设备控制IP 摄像机智能场景常…

“深度学习”学习日记。与学习相关的技巧 -- 参数的更新

2023.1.20 在神经网络的学习这一章&#xff0c;学习过了利用 梯度下降法 对参数进行更新&#xff0c;目的是找到是损失函数的值尽量小的参数&#xff1b;像解决这样的问题称为 最优化 。 由于参数空间十分复杂、参数规模十分庞大&#xff0c;导致“最优化”的过程变得困难。 …

C规范编辑笔记(十二)

往期文章&#xff1a; C规范编辑笔记(一) C规范编辑笔记(二) C规范编辑笔记(三) C规范编辑笔记(四) C规范编辑笔记(五) C规范编辑笔记(六) C规范编辑笔记(七) C规范编辑笔记(八) C规范编辑笔记(九) C规则编辑笔记(十) C规范编辑笔记(十一) 正文&#xff1a; 放假了&#xff…

【数据结构】万字深入浅出讲解顺序表(附原码 | 超详解)

&#x1f680;write in front&#x1f680; &#x1f4dd;个人主页&#xff1a;认真写博客的夏目浅石. &#x1f381;欢迎各位→点赞&#x1f44d; 收藏⭐️ 留言&#x1f4dd; &#x1f4e3;系列专栏&#xff1a;C语言实现数据结构 &#x1f4ac;总结&#xff1a;希望你看完…

智能矿山电子封条系统 YOLOv5

智能矿山电子封条系统通过yolov5深度学习技术&#xff0c;对现场画面进出口以及主要的井口等重要地方对矿井人员变化、生产作业执勤状态及出入井人员等状况实时监控分析监测。我们使用YOLO(你只看一次)算法进行对象检测。YOLO是一个聪明的卷积神经网络(CNN)&#xff0c;用于实时…

Google AIY Vision Kit安装及国内配置

Google AIY Vision Kit安装及国内配置1. AIY Vision Kit组装环节Step 1&#xff1a;收集其他附件选择1&#xff1a;使用AIY项目应用程序选择2&#xff1a;使用显示器、鼠标和键盘Step 2&#xff1a;检查硬件清单Step 3&#xff1a;构建AIY Vision KitStep 3.1&#xff1a;获取最…

旺店通·企业奇门和用友BIP接口打通对接实战

旺店通企业奇门和用友BIP接口打通对接实战接通系统&#xff1a;旺店通企业奇门旺店通是北京掌上先机网络科技有限公司旗下品牌&#xff0c;国内的零售云服务提供商&#xff0c;基于云计算SaaS服务模式&#xff0c;以体系化解决方案&#xff0c;助力零售企业数字化智能化管理升级…