解决Jpa中实体数据自动变更问题

您所在的位置:网站首页 JPA查询倒序第一条 解决Jpa中实体数据自动变更问题

解决Jpa中实体数据自动变更问题

2024-06-10 00:20| 来源: 网络整理| 查看: 265

目录 概述一、问题复现二、问题解析三、解决方案

概述

最近发现个问题,使用jpa对实体进行操作时,即使未调用保存或更新方法,对于实体的相关设值也会自动更新到数据库中

一、问题复现 @RunWith(SpringRunner.class) @SpringBootTest public class UserTest { @Autowired private UserInfoRepository userInfoRepository; @Test public void testUpdateEntity(){ UserInfo userInfo = userInfoRepository.get(2103031645422940000L); userInfo.setFullName("我不是管理员"); } }

数据库原始数据如下: image.png 为testUpdateEntity()添加事务注解,此时会自动将实体的相关变更持久化掉数据库中

@Test @Transactional //事务注解,添加之后jpa会自动把实体的相关变更持久化到数据库中 @Commit // 此注解是为了在单元测试中不让事务进行回滚,从而可以在数据库中看到数据的明显变化 public void testUpdateEntity(){ UserInfo userInfo = userInfoRepository.get(2103031645422940000L); userInfo.setFullName("我不是管理员"); }

执行testUpdateEntity()方法之后,输出日志如下 image.png 数据库数据变更如下 image.png

二、问题解析

经过查找资料得知,Hibernate实体对象的生命周期分为三种

瞬时状态(Transient)   通过new创建对象后,对象并没有立刻持久化,它并未与数据库中的数据有任何关联,此时Java对象的状态为瞬时状态。Session对于瞬时状态的Java对象是一无所知的,当对象不再被其他对象引用时,它的所有数据也就丢失了,对象将会被Java虚拟机按照垃圾回收机制处理。持久状态(Persistent)   当对象与Session关联,被Session管理时,它就处于持久状态。处于持久状态的对象拥有数据库标识(数据库中的主键值)。那么,对象是什么时候与Session发生关联的呢?有两种方法:   第一种,通过Sesison的查询接口,或者get()方法,或者load()方法从数据库中加载对象的时候,加载的对象是与数据库表中的一条记录关联的,此时对象与加载它的Session发生关联;   第二种,瞬时状态的对象,通过Session的save()方法或SaveOrUpdate()方法时,Java对象也与Session发生关联。 对于处于持久状态的对象,Session会持续跟踪和管理它们,如果对象的内部状态发生了任何变更,Hibernate会选择合适的时机(如事务提交时)将变更固化到数据库中。游离状态   处于持久状态的对象,脱离与其关联的Session的管理后,对象就处于游离状态。   处于游离状态的对象,Session无法保证对象所包含的数据与数据库中的记录一直,因为Hibernate已经无法感知对该对象的任何操作。   Session提供了两个方法(update()、merge()),将处于游离状态的对象,与一个新的Session发生关联。   此时,对象的状态就从游离状态重新转换为持久状态。

根据Hibernate实体生命周期可知,testUpdateEntity()中的userInfo处于持久化状态,一旦事务提交时,Hibernate会自动将userInfo的相关变更持久化到数据库中。

三、解决方案

既然知道Hibernate在事务提交时会自动将持久化状态的实体的变更持久化到数据库中,那么只要我们让实体脱离持久化状态即可避免这个问题。使用detach()使其脱离持久化状态,如下所示

@Test @Transactional @Commit public void testUpdateEntity(){ UserInfo userInfo = userInfoRepository.get(2103031645422940000L); userInfo.setFullName("我不是管理员111"); userInfoRepository.detach(userInfo); }

执行结果如下: image.png 数据库结果: image.png 未对数据库数据造成影响,成功解决问题。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3