Spring Boot JPA save之怪异

Spring Boot JPA save方法之怪异

项目场景

工作中的一个小需求,由于这个项目第一阶段只是引入,作为触发程序在后台跑数据,将下游的数据引入即可。所以不需要暴露在页面上。所以报错的话,是没有任何人感知的。所以需要提供一个监控程序,就是在遇到异常就记录下来,每日满足发生5次异常就发送邮件通知,通知后就不再通知。


问题描述

程序其实很简单,但是测试Demo的时候,由于使用的是JPA,使用的save方法保存,方法内部处理就是先判断isNew,然后去做update或者insert操作。问题是这个方法遇到数据库异常,比如主键冲突,虽然打印日志,但是异常实际上是被某个异常处理器处理掉了,根本报不出来。

java 复制代码
try{
    dao.save(entity);
}catch (Exception e) {
    log.error("error happened", e);
    monitorExceptionService.recordError(e);
}

这个错误日志是进入不到catch里面的。


问题原因

网上资料介绍要使用saveAndFlush方法,查看内部源码,其实就是多了一个flush方法。flush其实就是将sql预编译执行的结果发送给数据库得到的结果。save方法是在sql统一提交的才会报错,就是@Transactional整体结束的时候报错,所以catch不到报错。而saveAndFlush方法多的flush方法就是将sql结果发送到数据库,所以立马能得到报错。

源码如下:

java 复制代码
	@Transactional
	@Override
	public <S extends T> S saveAndFlush(S entity) {

		S result = save(entity);
		flush();

		return result;
	}

解决方案

就是将save方法改为saveAndFlush方法即可。

代码如下:

java 复制代码
try{
    dao.saveAndFlush(entity);
}catch (Exception e) {
    log.error("error happened", e);
    monitorExceptionService.recordError(e);
}

搞定收工!

相关推荐
Q_Q19632884755 小时前
python的漫画网站管理系统
开发语言·spring boot·python·django·flask·node.js·php
MaCa .BaKa5 小时前
38-日语学习小程序
java·vue.js·spring boot·学习·mysql·小程序·maven
Uranus^6 小时前
深入解析Spring Boot与Redis集成:高效缓存实践
java·spring boot·redis·缓存
椰椰椰耶6 小时前
【RabbitMQ】整合 SpringBoot,实现工作队列、发布/订阅、路由和通配符模式
spring boot·rabbitmq·java-rabbitmq
Uranus^7 小时前
使用Spring Boot和Spring Security构建安全的RESTful API
java·spring boot·spring security·jwt·restful api
编程乐学(Arfan开发工程师)7 小时前
06、基础入门-SpringBoot-依赖管理特性
android·spring boot·后端
编程乐学(Arfan开发工程师)7 小时前
05、基础入门-SpringBoot-HelloWorld
java·spring boot·后端
拾贰_C7 小时前
【SpringBoot】关于MP使用中配置了数据库表前缀的问题
数据库·spring boot·oracle
橘子海全栈攻城狮8 小时前
【源码+文档+调试讲解】党员之家服务系统小程序1
java·开发语言·spring boot·后端·小程序·旅游
冼紫菜8 小时前
Java开发中使用 RabbitMQ 入门到进阶详解(含注解方式、JSON配置)
java·spring boot·后端·rabbitmq·springcloud