1、问题症状描述

  最近在处理一个新需求问题,代码的大致逻辑是获取一个实体对象,调用该对象的set方法设置其中的某些字段,然后把修改后的实体作为
  参数供其他地方调用,根据返回值来决定是否更新这个实体到数据库中。按照这个思路调用了系统中的getByid方法,结果测试的时候发
  现,不管返回值是什么,这个实体最终都被更新到数据库中了。好吧,这明显是有问题的...

 
  

2、问题原因分析和解决办法

查看日志信息后发现,系统总是会打印出一个update语句。说明系统的确是执行了更新操作的,但是我并没有调用任何和update相关的方
法。跟踪代码发现,getById方法其实是调用了hibernate的get方法。嗯,果然,问题出在这里了.....Hibernate的get和load方法查询出
的实体都是持久化对象,拿到该对象后,如果你调用了该对象的set方法,那么在事务递交的时候,Hibernate会把你设置的值自动更新到数据库中。

3、相关知识扩展

Hibernate的几种实体状态:

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

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

3.脱管:

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

码魇
485 声望15 粉丝