1、问题症状描述
      最近在处理一个新需求问题,代码的大致逻辑是获取一个实体对象,调用该对象的set方法设置其中的某些字段,然后把修改后的实体作为参数供其他地方调用,根据返回值来决定是否更新这个实体到数据库中。

按照这个思路调用了系统中的getByid方法,结果测试的时候发现,不管返回值是什么,这个实体最终都被更新到数据库中了。好吧,这明显是有问题的....【没有问题的代码不是好代码 - -|| 】

2、问题原因分析和解决办法
        2.1  查看日志信息后发现,系统总是会打印出一个update语句。说明系统的确是执行了更新操作的,但是我并没有调用任何和update相关的方法。

2.2  跟踪代码发现,getById方法其实是调用了hibernate的get方法。嗯,果然,问题出在这里了.....

2.3  Hibernate的get和load方法查询出的实体都是持久化对象,拿到该对象后,如果你调用了该对象的set方法,那么在事务递交的时候,Hibernate会把你设置的值自动更新到数据库中。

解决办法:

在获取实体对象后,调用下getHibernateTemplate().evict(entity)方法,该方法的作用是把持久化对象变成托管状态。变成托管状态后,Hibernate就不会再去自动更新该实体。

3、相关知识扩展
Hibernate的几种实体状态:

1.瞬态:
  一个实体通过new操作符创建后,没有和Hibernate的Session建立关系,也没有手动赋值过该实体的持久化标识(持久化标识可以认为是映射表的主键)。
               此时该实体中任何属性的更新都不会反映到数据库表中。
2.持久化:
               当一个实体和Hibernate的Session创建了关系,并获取了持久化标识,而且在Hibernate的Session生命周期内存在。
               此时针对该实体任何属性的更改都会直接影响到数据库表中一条记录对应字段的更新,即与数据库表同步。
3.脱管:
              当一个实体和Hibernate的Session创建了关系,并获取了持久化标识,而此时Hibernate的Session生命周期结束,实体的持久化标识没有被改动过。
              针对该实体任何属性的修改都不会及时反映到数据库表中。

关闭session可以使实体从持久化状态转为托管状态。

知识扩展部分参考自 http://blog.csdn.net/sunhuwh/article/details/9183539 ,感谢作者。

转帖请注明文章来源: http://blog.csdn.net/yang_lover/article/details/45057181

---------------------
作者:没有桃子的阿狸
来源:CSDN
原文:https://blog.csdn.net/yang_lover/article/details/45057181

hibernate查询出的实体,set值后,自动更新到数据库的更多相关文章

  1. hibernate查询出的实体,set值后,自动更新到数据

    如图: 故事背景:(p.s.我们的项目没有正确配置事务xml文件,未明原因导致事务定义的规则不起作用)获取一个资讯对象,调用该对象的set方法设置其中的content字段,然后把修改后的实体丢到官网首 ...

  2. ASPX 关闭子窗口后自动更新父窗口

    Response.Write("<script language:javascript>javascript:window.close();</script>&quo ...

  3. sql hibernate查询转换成实体或对应的VO Transformers

    sql查询转换成实体或对应的VO Transformers //addScalar("id") 默认查询出来的id是全部大写的(sql起别名也无效,所以使用.addScalar(& ...

  4. hibernate查询出的数据和数据库不一致

    之前直接使用hibernate的时候就出现过已经进行物理存储后的数据,查询不出来的情况,既然是已经存储后的数据,说明事务已经提交,想必问题出在查询时,查询的缓存,没有查询数据库.时有时无就很奇怪. 现 ...

  5. MySQL中group_concat函数 --- 很有用的一个用来查询出所有group by 分组后所有 同组内的 内容

    本文通过实例介绍了MySQL中的group_concat函数的使用方法,比如select group_concat(name) . MySQL中group_concat函数 完整的语法如下: grou ...

  6. oracle查询查询出某字段为空后前台不显示的小测试1

    1.nvl(,''),后台会打印null,前台不显示 2不处理,后台显示null,前台不显示 3.nvl(,' '),后台显示" ",前台显示“ ”

  7. DataGridView编辑后立即更新到数据库的两种方法

    DataGridView控件是微软预先写好的一个显示数据的控件,功能非常强大,可以显示来自数据库表的数据和XML等其他来源的数据. 方法一:基于DataAdapter对象创建一个CommandBuli ...

  8. Centos6.8实现SVN提交后自动更新目录

    1.创建svn目录 mkdir /var/www/project 2.从服务器的本地svn上checkout最新版本代码到www目录下的project文件夹,注意本地svn服务器地址和端口号是在启动s ...

  9. docker-compose在dockerfile更新后自动更新image

    比如在dockerfile里需要新安装包 形如 加一行 RUN pip3 install XXX 之后,希望docker-compose能更新镜像, 然后启动容器 只需要启动时使用 --build即可 ...

随机推荐

  1. Newtonsoft.Json JsonHelper

    Json.net 简单封装 using System; using System.Linq; using Newtonsoft.Json; using Newtonsoft.Json.Serializ ...

  2. 如果从码云上git clone项目

    1.本地找个文件夹右击选择 git base 2.输入地址 弹出一个窗口 需要输入用户名.密码(就是码云的登录名.密码) 3.完成

  3. 谈谈我对"闭包"的理解

    一.什么是闭包和闭包的几种写法和用法 1.什么是闭包闭包,官方对闭包的解释是:一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分.闭包的特点: 1. 作 ...

  4. Linux上jdk安装及环境变量设置

    1.jdk下载和安装 (1)http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html下载需 ...

  5. windows10企业版2016长期服务版激活 -------转

    原地址: https://blog.csdn.net/chaoyu168/article/details/79241506 win10 2016 长期服务版的ISO文件中本身就带有KMS激活KEY,不 ...

  6. linux 模拟生成 CAN 设备

    /************************************************************************************** * linux 模拟生成 ...

  7. BZOJ4571: [Scoi2016]美味【主席树】【贪心】

    Description 一家餐厅有 n 道菜,编号 1...n ,大家对第 i 道菜的评价值为 ai(1≤i≤n).有 m 位顾客,第 i 位顾客的期 望值为 bi,而他的偏好值为 xi .因此,第 ...

  8. Redis学习笔记-常用命令篇(Centos7)

    redis提供了丰富的命令,这些命令可以在linux终端使用.在各类语言中,这些命令都有对应的方法. 一.键值相关 1.keys 返回满足给定pattern的所有key 127.0.0.1:6379& ...

  9. Hive之 数据存储

    首先,Hive 没有专门的数据存储格式,也没有为数据建立索引,用户可以非常自由的组织 Hive 中的表,只需要在创建表的时候告诉 Hive 数据中的列分隔符和行分隔符,Hive 就可以解析数据. 其次 ...

  10. bzoj 2839 集合计数——二项式反演

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2839 设 \( g(i) \) 表示至少有 i 个, \( f(i) \) 表示恰好有 i ...