Hibernate数据持久化及update更新问题

时间:2021-03-10 20:39:09

关于HibernateSession update问题

Hibernate在进行数据处理时实现了数据的持久化。持久化对象分为三种状态;分为:瞬时态、持久态、托管态;处理持久态的对象也称为PO(Persistence Object),瞬时对象和脱管对象也称为为VOValue Object

 

瞬时态

当由new 命令开辟内存空间存储的JAVA 对象称之为瞬时对象。因为这种对象还没有进入数据库,由JAVA的虚拟机进行回收。瞬时对象在内存中是孤立存在的。它是携带信息的载体,不和数据库有任何的关联。在Hibernate中,可以通过Save()SaveOrUpdate()方法将一个瞬时对象与数据库进行关联。并将数据插入到数据库中,此时此瞬时对象将变成持久化对象了。

 

持久态

处理持久态的对象在数据库中具有相应的记录,并拥有一个持久化的标识。如果用HibernateDelete()方法,对应的持久对象将变成瞬时对象。因为数据库中对应的记录已经被删除。该对象不再与数据库有任何的关联。

 

Session执行Close()或clear()evict()之后,持久对象将变成脱管对象,此时该对象虽然具有数据库的识别值,但是它已经不在Hibernate持久层的管理之下。

持久对象具有和Session关联的特点和在数据库中有相关记录的特点。

 

脱管态

当与某持久对象关联的Session被关闭后,该持久对象将变成脱管对象。当脱管对象再次被关联到Session上时,再次将变成持久对象。

脱管对象拥有数据库识别值,可以通过update()saveOrUpdate()等方式,转变为持久对象。

Hibernate中的update()方法不是更新操作,只是将相关的对象由脱管态转为持久态与数据进行关联而已。

 

脱管对象本质上与瞬时对象相同。在没有任何变量引用它时,JVM会在适当的时候将它收回。

脱管对象比瞬时对象多了一个数据库识别值。

 

 

因此其于以上三个特点,当我们用HibernategetCurrentSession打开Session并进行数据更新操作时,此时的对象为瞬时对象或脱管对象。因此需要调用update将此瞬时对象或脱管对象转为持久对象。当转为持久对象时,Hibernate会自动对数据进行更新。如果调用更新后而没有调用session.flush()方法,此时虽然数据已经更新但是由于没有进行写入数据库,数据库的值依然还是没有改变的。因为在调用flush之前,数据是在内存中存储,并没有实时同步到数据库中。即flush是操作的持久态相关的数据,update是操作的脱管态相关的数据。

 

Session中的lockupdate是有区别的。Lock是把没有改动过的脱管态对象转变为持久态对象,等待手动flush或自动flush,而Update则是不管是否已经修改过,都将其转变为持久态对象。等待手动flush或自动flush

 

Session中的clear是完成将session中的缓存清除。而evcit则是清除缓存中某个持久化的对象。即只把某个持久化的对象从缓存中移除。

 

HibernategetCurrentSession方法和openSession方法虽然都是Hibernate提供给我们取得session的方法,但还是有本质的区别的。openSession需要我们手动进行关闭连接,如果多次没有关闭会造成连接池溢出问题,而getCurrentSession则是由Hibernate自动管理的。


问题总结:在使用Hibernate进行save()、update()等操作时,由于save是对瞬时对象的操作,将瞬时对象转换为持久对象。而update()在执行中只是将当前的对象与数据库进行关联,形成持久对象。也就是说在进行操作时为什么执行了update,而数据确没有更新的原因。如果是Hibernate刚上手,是比较容易出这个问题的。