提问人:Mazai 提问时间:8/5/2023 最后编辑:PinoMazai 更新时间:8/11/2023 访问量:65
将 redis 中的数据更新到数据库时发生空指针异常
A null pointer exception occurred while updating data in redis to the database
问:
我做了一个博客项目,我希望用户每次点击博客,页面浏览量都会自动更新,我用redis来存储数据,每隔一段时间,redis中的数据就会更新到数据库中,但是当我想将当前登录用户ID更新到数据库中时, 发生异常。我希望你能帮我弄清楚问题出在哪里,谢谢。
这是我的实现类:
@Component
public class UpdateViewCountJob {
@Autowired
private RedisCache redisCache;
@Autowired
private ArticleService articleService;
@Scheduled(cron = "0/5 * * * * ?")
public void updateViewCount(){
//获取redis中的浏览量
Map<String, Integer> viewCountMap = redisCache.getCacheMap("article:viewCount");
List<Article> articles = viewCountMap.entrySet().stream()
.map(entry -> new Article(Long.valueOf(entry.getKey()), entry.getValue().longValue()))
.collect(Collectors.toList());
Long userId = SecurityUtils.getUserId();
for (Article article : articles) {
article.setUpdateBy(userId);
}
//更新到数据库中
articleService.updateBatchById(articles);
}
}
这是我用 mybatisplus 实现的自动填充函数的类:
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
@Override
public void insertFill(MetaObject metaObject) {
Long userId = null;
userId = SecurityUtils.getUserId();
this.setFieldValByName("createTime", new Date(), metaObject);
this.setFieldValByName("createBy",userId , metaObject);
this.setFieldValByName("updateTime", new Date(), metaObject);
this.setFieldValByName("updateBy", userId, metaObject);
}
@Override
public void updateFill(MetaObject metaObject) {
this.setFieldValByName("updateTime", new Date(), metaObject);
this.setFieldValByName("updateBy", SecurityUtils.getUserId(), metaObject);
}
}
错误消息如下:
2023-08-05 13:42:05.005 ERROR 20388 --- [ scheduling-1] o.s.s.s.TaskUtils$LoggingErrorHandler : Unexpected error occurred in scheduled task
java.lang.NullPointerException: null
at com.blog.framework.utils.SecurityUtils.getLoginUser(SecurityUtils.java:13) ~[classes/:na]
at com.blog.framework.utils.SecurityUtils.getUserId(SecurityUtils.java:29) ~[classes/:na]
at com.blog.job.UpdateViewCountJob.updateViewCount(UpdateViewCountJob.java:32) ~[classes/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_131]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_131]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_131]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_131]
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_131]
at java.util.concurrent.FutureTask.run(FutureTask.java:266) [na:1.8.0_131]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180) [na:1.8.0_131]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293) [na:1.8.0_131]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_131]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_131]
at java.lang.Thread.run(Thread.java:748) [na:1.8.0_131]
SecurityUtils 类,如下所示:
public class SecurityUtils {
/**
* 获取用户
**/
public static LoginUser getLoginUser() {
return (LoginUser) getAuthentication().getPrincipal();
}
/**
* 获取Authentication
*/
public static Authentication getAuthentication() {
return SecurityContextHolder.getContext().getAuthentication();
}
public static Boolean isAdmin(){
Long id = getLoginUser().getUser().getId();
return id != null && id.equals(1L);
}
public static Long getUserId() {
return getLoginUser().getUser().getId();
}
}
让我感到困惑的是,当我注释掉 MyMetaObjectHandler 类中自动填充用户 ID 的代码时,没有错误,如下所示:
@Override
public void updateFill(MetaObject metaObject) {
this.setFieldValByName("updateTime", new Date(), metaObject);
// this.setFieldValByName("updateBy", SecurityUtils.getUserId(), metaObject);
}
如果你能帮我解决这个问题,我将非常感谢你!
答: 暂无答案
评论