解决JPA对查询对象set属性值导致数据更新的问题
问题描述
1、开启了数据库事务
2、通过EntityManager执行查询,获得返回对象
3、代码业务逻辑处理,其中有对象set属性值的操作
4、没有执行过JPA的save方法或者update语句
5、提交数据库事务,发现数据库中对应的数据更新成了新的属性值
问题复现
@Transactional
@Override
public void selectAndFlush(String id) {
User user = crudDao.selectByPrimaryKey(id);
user.setName("testFlushNotUpdateDB");
}
Hibernate: selectuser0_.AGE as AGE8_0_, user0_.CARD as CARD9_0_, user0_.NAME as NAME10_0_, user0_.PRICE as PRICE11_0_ from USER user0_ where user0_.ID=? Hibernate: update USER set AGE=?, CARD=?, NAME=?, PRICE=? where ID=?
可以看到在set方法之后JPA自动帮我们执行了update操作
问题原因
根本原因是因为我们在执行查询以后,查询结果对象在EntityManager上下文中进行了一级缓存,执行set方法以后缓存对象状态【持久态】,事务提交时会自动帮我们flush到数据库中,导致数据被更新,下图为一级缓存对象:

解决方法
这里提供4中解决方法:
1、提交事务之前执行EntityManager.clear()方法,清理缓存对象
2、业务代码在不需要更新数据时避免直接对查询对象进行set操作,可以使用BeanUtils.copyProperties()方法复制对象,再进行set操作
3、使用EntityManager.evict()方法清理指定对象
4、修改JPA的FlushMode,没有测试过,理论可行,代码如下:
((Session) getEntityManager().getDelegate()).setFlushMode(FlushMode.MANUAL);
解决JPA对查询对象set属性值导致数据更新的问题的更多相关文章
- JQuery 操作对象的属性值
通过JQuery去操作前台对象(div,span...)的属性是很常见的事情,本文就简单的介绍几种操作情形. 1):通过属性值去获取对象 2):用JQuery去修改对象的属性值 3):获取并修改对象的 ...
- jquery attr()方法 添加,修改,获取对象的属性值。
jquery attr()方法 添加,修改,获取对象的属性值. jquery中用attr()方法来获取和设置元素属性,attr是attribute(属性)的缩写,在jQuery DOM操作中会经常用到 ...
- 读匿名object对象的属性值
读匿名object对象的属性值 1.定义读object对象值的功能方法 public static class StaticClass { public static string ValueByKe ...
- WPFS数据绑定(要是后台类对象的属性值发生改变,通知在“client界面与之绑定的控件值”也发生改变须要实现INotitypropertyChanged接口)
WPFS数据绑定(要是后台类对象的属性值发生改变,通知在"client界面与之绑定的控件值"也发生改变须要实现INotitypropertyChanged接口) MainWindo ...
- 获取JSON对象的属性值
1.问题背景 有一个json对象,其中有键值对,那怎样获取json对象中属性值 2.实现源码 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 ...
- JQuery修改对象的属性值
JQuery修改对象的属性值 用到的便是JQuery提供的attr方法,获取属性值的基本结构为:$(obj).attr("属性名"):修改属性值的结构为:$(obj).attr(& ...
- eclipse 中main()函数中的String[] args如何使用?通过String[] args验证账号密码的登录类?静态的主方法怎样才能调用非static的方法——通过生成对象?在类中制作一个方法——能够修改对象的属性值?
eclipse 中main()函数中的String[] args如何使用? 右击你的项目,选择run as中选择 run configuration,选择arguments总的program argu ...
- webdriver高级应用- 改变一个页面对象的属性值
适用于一些无法操作的元素,可以直接改他的属性从而操作,代码如下: #encoding=utf-8 from selenium import webdriver import unittest impo ...
- spring:为javabean的集合对象注入属性值
spring:为JavaBean的集合对象注入属性值 在 spring 中可以对List.Set.Map 等集合进行配置,不过根据集合类型的不同,需要使用不同的标签配置对应相应的集合. 1.创建 Ts ...
- 使用java中的反射获得object对象的属性值
知识点:使用java中的反射获得object对象的属性值 一:场景 这两天开发代码时,调用别人的后台接口,返回值为Object对象(json形式的),我想获得object中指定的属性值,没有对应的ge ...
随机推荐
- Feign的超时时间如何设置,我研究了4种情况
大家好,我是三友~~ 今天来聊一聊前段时间看到的一个面试题,也是在实际项目中需要考虑的一个问题,Feign的超时时间如何设置? Feign的超时时间设置方式并不固定,它取决于Feign在项目中是如何使 ...
- 微服务集成seata完成分布式事务,解决数据不一致问题
细心的盆友可能已经发现了,我们的跨行转账并没有保证数据一致性,比如小明扣除了100,但是因为各种问题小红在添加100金额的时候遇到了异常,这个时候数据就出现不一致性 我们可以选择seata来进行分布式 ...
- vlak
2023-7-14 题目 luogu题目传送门 题目描述 Nina 和 Emilija 正在玩一个特殊的游戏.这个游戏是在一张最开始为空白的纸上进行的.在每一个人的行动回合内,这个人会在这张纸上当前的 ...
- Controller 层代码技巧
Controller 层代码技巧 前言 本篇主要要介绍的就是controller层的处理,一个完整的后端请求由4部分组成: 接口地址(也就是URL地址) 请求方式(一般就是get.post,当然还有p ...
- 一次Python本地cache不当使用导致的内存泄露
背景 近期一个大版本上线后,Python编写的api主服务使用内存有较明显上升,服务重启后数小时就会触发机器的90%内存占用告警,分析后发现了本地cache不当使用导致的一个内存泄露问题,这里记录一下 ...
- Docker部署cas
一.首先安装cas镜像 1.拉取cas docker镜像 docker pull apereo/cas 2.启动容器: docker run --name cas -p 8443:8443 -p 8 ...
- glog 日志库简介与测试【GO 常用的库】
〇.前言 golang/glog 是 C++ 版本 google/glog 的 Go 版本实现,基本实现了原生 glog 的日志格式. 在 Kuberntes 中,glog 是默认日志库.因此需要详细 ...
- MySQL实战实战系列 01 基础架构:一条SQL查询语句是如何执行的?
这是专栏的第一篇文章,我想来跟你聊聊 MySQL 的基础架构.我们经常说,看一个事儿千万不要直接陷入细节里,你应该先鸟瞰其全貌,这样能够帮助你从高维度理解问题.同样,对于 MySQL 的学习也是这样. ...
- 地理探测器Geodetector下载、使用、结果分析方法
本文介绍Geodetector软件的下载方法,以及地理探测器分析的完整操作,并对其结果加以解读. 首先,我们介绍Geodetector软件的下载方法.进入软件官网,可以看到其中的第四个部分为软 ...
- C51单片机开发
C51单片机开发笔记 定时器 C51中的定时器和计数器是同一个硬件电路支持的,通过寄存器配置不同,就可以将他当做定时器 或者计数器使用. 确切的说,定时器和计数器区别是致使他们背后的计数存储器加1的信 ...