BUG
Hibernate: insert into tb_refresh_token (create_time, refresh_token, token_key, update_time, user_id, id) values (?, ?, ?, ?, ?, ?)
Hibernate: insert into tb_comment (article_id, content, create_time, parent_content, state, update_time, user_avatar, user_id, user_name, id) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
[2021/02/03-11:58:22] [http-nio-8080-exec-6] [WARN ] [org.hibernate.engine.jdbc.spi.SqlExceptionHelper] : SQL Error: 1048, SQLState: 23000
[2021/02/03-11:58:22] [http-nio-8080-exec-6] [ERROR] [org.hibernate.engine.jdbc.spi.SqlExceptionHelper] : Column 'user_id' cannot be null
[2021/02/03-11:58:22] [http-nio-8080-exec-6] [ERROR] [org.hibernate.internal.ExceptionMapperStandardImpl] : HHH000346: Error during managed flush [org.hibernate.exception.ConstraintViolationException: could not execute statement]
[2021/02/03-11:58:22] [http-nio-8080-exec-6] [ERROR] [org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/].[dispatcherServlet]] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement] with root cause
com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Column 'user_id' cannot be null

源码
/**
*
* @param response
* @param userFromDb
* @return 返回token_key
*/
private String createToken(HttpServletResponse response, SobUser userFromDb) {
int deleteResult = refreshTokenDao.deleteAllByUserId(userFromDb.getId());
log.info("deleteResult of refresh token..." + deleteResult);
//生成token
Map<String, Object> claims = new ClaimsUtils().sobUser2Claims(userFromDb);
//token默认是两个小时
String token = JwtUtil.createToken(claims);
//返回token的md5的值,token会保存到redis里
//前端访问的时候,携带token的md5key,从redis中获取即可
String tokenKey = DigestUtils.md5DigestAsHex(token.getBytes());
//保存到redis中,有效期是2小时,key是tokenKey
redisUtils.set(Constants.User.KEY_TOKEN + tokenKey,token, Constants.TimeValue.HOUR_2);
//把tokenKey写到cookies里面
//这个要动态获取,可以从request里面获取
//后面提供一个工具类使用
CookieUtils.setUpCookie(response,Constants.User.COOKIE_TOKE_KEY,tokenKey);
//生成refreshToken
String refreshTokenValue = JwtUtil.createRefreshToken(userFromDb.getId(), Constants.TimeValue.MONTH);
//TODO:保存到数据库里面
//refreshToken,tokenKey,用户ID,创建时间,更新时间
RefreshToken refreshToken = new RefreshToken();
refreshToken.setId(idWorker.nextId() + "");
refreshToken.setRefreshToken(refreshTokenValue);
refreshToken.setUserId(userFromDb.getId());
refreshToken.setTokenKey(tokenKey);
refreshToken.setCreateTime(new Date());
refreshToken.setUpdateTime(new Date());
refreshTokenDao.save(refreshToken);
return tokenKey;
}
/**
* 本质:通过携带的token_key检查用户是否有登陆,如果登陆就返回用户信息
* @param request
* @param response
* @return
*/
@Override
public SobUser checkSobUser(HttpServletRequest request, HttpServletResponse response) {
//拿到token_key
String tokenKey = CookieUtils.getCookie(request, Constants.User.COOKIE_TOKE_KEY);
log.info("checkSobUser tokenKey == > " +tokenKey);
SobUser sobUser = parseByTokenKey(tokenKey);
if (sobUser == null) {
//1、说明解析出错 ,token过期了,去mysql查询refreshToken
RefreshToken refreshToken = refreshTokenDao.findOneByTokenKey(tokenKey);
//2、如果不存在,就是当前访问没有登陆
if (refreshToken == null) {
log.info("refresh token is null... ");
return null;
}
//3、如果存在,就解析refreshToken
try{
JwtUtil.parseJWT(refreshToken.getRefreshToken());
//5、如果refreshToken有效,创建新的token,和新的refreshToken
String userId = refreshToken.getUserId();
SobUser userFromDb = userDao.findOneById(userId);
//删掉refreshToken的记录
String newTokenKey = createToken(response, userFromDb);
//返回token
log.info("create new token and refresh token...");
return parseByTokenKey(newTokenKey);
}catch (Exception e1){
log.info("refresh token is 过期... ");
//4、如果refreshToken过期了,提示当前访问没有登陆,提示用户登录
return null;
}
}
return sobUser;
}
private SobUser parseByTokenKey(String tokeKey){
String token = (String) redisUtils.get(Constants.User.KEY_TOKEN + tokeKey);
log.info("parseByTokenKey token == > " + token);
if (token != null) {
//不为空,解析token
try{
Claims claims = JwtUtil.parseJWT(token);
return ClaimsUtils.claims2SobUser(claims);
}catch (Exception e){
log.info("parseByTokenKey == > " + tokeKey + "token过期了...");
return null;
}
}
return null;
}
@PostMapping("/comment")
public ResponseResult testComment(@RequestBody Comment comment, HttpServletRequest request,HttpServletResponse response){
String content = comment.getContent();
log.info("comment content == > " + content);
//还有得知评论的是谁,对这个评论,身份进行确定
String tokenKey = CookieUtils.getCookie(request, Constants.User.COOKIE_TOKE_KEY);
if(tokenKey == null){
return ResponseResult.FAILED("账号未登录");
}
SobUser sobUser = userService.checkSobUser(request, response);
if (sobUser == null) {
return ResponseResult.FAILED("账号未登录");
}
comment.setUserId(sobUser.getId());
comment.setUserAvatar(sobUser.getAvatar());
comment.setUserName(sobUser.getUserName());
comment.setCreateTime(new Date());
comment.setUpdateTime(new Date());
comment.setId(idWorker.nextId() + "");
commentDao.save(comment);
return ResponseResult.SUCCESS("评论成功!");
}
是我数据库的原因吗?
我猜测,错误是因为,你的文章id问题。
因为评论哪里,评论使用了外键:文章id,
你把一个存在的文章,正常的文章id,提交评论试试。
或者看看你的table对应的实体类是否和数据库一致
没有就是没有,计算机又不会骗人。要么你字段错了,对不上。检查一下吧。打断点就可以知道问题在哪了。
对了,你的代码,最好点击编辑栏里的代码按钮输入,要不看起来一坨狗屎一样,很累的。