技术文摘
JPA查询同一对象,修改值后再次查询却得到更新后的值的原因
JPA查询同一对象,修改值后再次查询却得到更新后的值的原因
在使用JPA(Java Persistence API)进行开发时,开发者可能会遇到这样一个现象:对同一对象进行查询,在修改其值后再次查询,得到的却是更新后的值,而非初始查询时的值。这一情况常常令人困惑,下面我们就来深入剖析其中的原因。
JPA有一个重要的特性——一级缓存(也称为实体管理器缓存)。当通过JPA的实体管理器(EntityManager)查询一个对象时,该对象会被放入到一级缓存中。在同一个事务内,如果再次查询相同的对象,JPA首先会检查一级缓存。如果缓存中存在该对象,就直接从缓存中返回,而不会再次执行数据库查询操作。
假设我们执行了一个查询操作,获取到一个对象A。之后对对象A的某些属性进行了修改,此时,一级缓存中的对象A也已经是修改后的状态。当再次发起对相同对象的查询时,由于一级缓存的存在,JPA不会从数据库重新读取初始状态的对象,而是直接返回缓存中修改后的对象A。
另外,JPA的持久化上下文(Persistence Context)也在其中起到了关键作用。持久化上下文负责管理实体的生命周期,它会跟踪实体的状态变化。当一个实体被加载到持久化上下文中后,对其进行的任何修改都会被持久化上下文所感知。在后续的查询中,持久化上下文会确保返回最新状态的实体。
要避免这种情况,有几种常见的方法。一种是使用EntityManager的detach方法,将实体从持久化上下文中分离出来,这样在修改后再次查询时,就会从数据库中获取原始值。另一种方法是在新的事务中进行查询,因为不同事务有各自独立的一级缓存,新事务不会受到之前事务中缓存的影响,从而能获取到数据库中的原始值。
了解JPA的一级缓存和持久化上下文机制,对于理解为什么修改值后再次查询会得到更新后的值至关重要。掌握这些原理,能帮助开发者更高效地利用JPA进行数据访问层的开发,避免一些潜在的问题。
- Docker 编辑 Dockerfile 添加 php7.2 acpu 时的问题
- Containerd 容器的 yum 安装及二进制安装
- K8s-helm 简介与基本概念深度解析
- K8s 中 Ingress-Nginx 的详解与部署方案
- Docker Machine 安装极狐 GitLab 全流程解析
- Dockerfile 脚本定制镜像的使用方法
- Docker 容器使用全解析
- VMware 虚拟机安装流程与镜像文件下载全解
- docker-compose 实现 6 台服务器(3 主 3 从)的 Redis 多机集群启动
- docker-compose 启动 redis 集群的实现流程
- VMware 虚拟机彻底卸载的详尽步骤记录
- docker-compose 实现 mysql 双机热备互为主从的方法
- Windows Server 2016 中文版安装 Docker 详细步骤
- Docker 常见命令整合(涵盖镜像及容器命令)
- Docker-Compose 容器集群的高效编排策略