首页 > 数据库 >SpringDataJpa对拿到的对象进行set,但是不save,数据库也能自动更新,由于使用了注解 @Transactional事务进行处理

SpringDataJpa对拿到的对象进行set,但是不save,数据库也能自动更新,由于使用了注解 @Transactional事务进行处理

时间:2023-08-01 19:56:52浏览次数:74  
标签:set 数据库 实体 SpringDataJpa 自动更新 save

SpringDataJpa对拿到的对象进行set,但是不save,数据库也能自动更新,由于使用了注解 @Transactional事务进行处理
原文链接:https://blog.csdn.net/qq_19903753/article/details/103367252

SpringDataJpa对拿到的对象进行set,但是不save,数据库也能自动更新

概述

今天在进行code review的时候,发现有一段代码很奇怪,就是标题所说的,将数据库的实体拿出来后,执行setXxx()更新,但是最后没有对实体进行save操作,数据库居然也能自动更新了。

代码如下:

/**
 * 这是一个举例子的方法,从数据库拿到实体->进行set更新且不save
*/
@Transactional
public void exampleMethod() {
    Optional<Food> foodOptional = foodDAO.findById(1L);
    // 如果不存在
    if(!foodOptional.isPresent()) {
        logger.info("the food 1L is not found!");
        return;
    }
	// 拿到实体
    Food food = foodOptional.get();
    // 对实体进行set更新状态
    food.setState(FoodState.EATTED);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

执行结果:

没想到,数据库里的 food :1L 的状态变成了EATTED,但是我们没有进行save操作呀。

分析

我们使用的foodDAO.findById(1L)方法,查出来的是数据库的持久化对象,SpringDataJpa在事务完成的时候,会自动提交修改,这是因为SpringDataJpa底层还是利用hibernate实现的,对于hibernate,我们需要去了解实体的状态。

这里去搜到了一篇文章:hibernate实体状态

Hibernate实体状态的定义
1.瞬态:
一个实体通过new操作符创建后,没有和Hibernate的Session建立关系,也没有手动赋值过该实体的持久化
标识(持久化标识可以认为是映射表的主键)。此时该实体中任何属性的更新都不会反映到数据库表中。

2.持久化:
当一个实体和Hibernate的Session创建了关系,并获取了持久化标识,而且在Hibernate的Session生命周期内
存在。此时针对该实体任何属性的更改都会直接影响到数据库表中一条记录对应字段的更新,即与数据库表同步。

3.脱管:
当一个实体和Hibernate的Session创建了关系,并获取了持久化标识,而此时Hibernate的Session生命周期结
束,实体的持久化标识没有被改动过。针对该实体任何属性的修改都不会及时反映到数据库表中。

出现没有save确自动更新的情况,就是因为我们拿到的是持久化实体,在Service层自动提交事务的时候,会根据持久化对象自动更新数据库信息!

标签:set,数据库,实体,SpringDataJpa,自动更新,save
From: https://www.cnblogs.com/sunny3158/p/17598928.html

相关文章

  • 格式化输出\pset命令详解
    语法"\pset"命令的语法如下:\pset[option[value]]postgres@linuxpg51:5432=#\psetborder1columns0csv_fieldsep','expandedofffieldsep'|'fieldsep......
  • 关于安装python包执行setup.py文件报错类似提示line 155 warnings.warn(f'Cannot copy
    首先可以确定世python语法问题,一般来说python3.6以后字符串使用f是没有问题的,后来发现问题所在,原来我安装好python以后,没有将python命令软连接到python3,导致python命令其实一直是使用的python2,所以才会有这样的问题。所以,当python3安装好以后,一定要重新指向软连接,还有pip3,也要指向......
  • weekset和weekmap
     在ES6中,WeakSet和WeakMap是两种特殊的集合数据结构,它们与Set和Map相似,但具有一些不同之处。WeakSet:WeakSet是一种弱引用集合,它只能存储对象,而不能存储原始值(如字符串、数字等)。WeakSet中存储的对象都是弱引用,如果没有其他地方引用这些对象,垃圾回收机制会自动回收......
  • js set和map详解
      当我们需要存储唯一值的集合时,可以使用Set。Set是一种有序的、无重复值的集合,它可以存储任何类型的值,包括原始值和对象。下面是使用Set的示例:Copy//创建一个SetconstmySet=newSet();//添加值mySet.add(1);mySet.add(2);mySet.add(3);//删除值......
  • js weekset和weekmap详解
    在JavaScript中,WeakSet和WeakMap是Set和Map的变体,它们的特点是只能存储对对象的弱引用。这意味着,如果一个对象只被WeakSet或WeakMap引用,而没有被其他地方引用,那么它可能会被垃圾回收器清理掉。这在某些情况下非常有用,比如处理缓存或临时数据等。WeakSet和WeakMap的用法与Set和Map......
  • 巧用Python中set集合对比两个文本文件
    """1.读取文件2.使用set集合s.add(x)添加xins是否在集合中>>>basket={'apple','orange','apple','pear','orange','banana'}>>>print(basket)           #这......
  • Maven配置中pom.xml和setting.xml之间的关系
    在日常的开发中,我们拿IDEA举例,一般会在电脑上自行下载安装Maven,然后在IDEA中配置我们安装的Maven路径,通过修改setting.xml文件,例如配置公共的镜像仓库地址,来提高依赖下载速率;或者配置内部私有的镜像仓库地址,来引入一些私有的依赖等等。1、如何从指定的镜像仓库下载依赖如下图在......
  • spark dataset dataframe 动态添加列
    需求利用SparkSQL计算每一行数据的数据质量,如果数据不为NULL或者不为空字符串(或者符合正则表达式),那么该字段该行数据积一分网上解决方案https://blog.csdn.net/Code_LT/article/details/87719115https://blog.csdn.net/LLJJYY001/article/details/88964961?spm=1001.210......
  • idea - 在setting 关闭 git Analyze code后 push 时自动开启 - 解决
    不要在setting里修改,需要在 这个齿轮中修改才生效 就这么奇怪 ......
  • Android学 App自动更新之通知栏下…
    Android学习系列(2)--App自动更新之通知栏下载见证过博客园的多次升级,你也希望你的软件通过更新发布新特性通知用户吧,是的。这篇文章是android开发人员的必备知识,是我特别为大家整理和总结的,不求完美,但是有用。 1.设计思路,使用VersionCode定义为版本升级参数。android为我......