hibernate POJO对像 状态及转换


 

当应用程序通过new语句创建了一个对象,这个对象的生命周期就开始了,当不再有任何引用变量引用它,这个对象就结束生命周期,它占用的内存就可以被JVM的垃圾回收器回收。对于需要被持久化的POJO对象,在它的生命周期中,可处于以下三个状态之一: 

 

(1) 临时状态(transient)

 

刚刚用new创建,还没有被持久化,不处于Session的缓存中。处于临时状态的Java对象被称为临时对象。

 

(2) 持久化状态(persistent)

 

已经被持久化,加入到Session的缓存中。处于持久化状态的Java对象被称为持久化对象。

 

(3) 游离状态(detached)

 

已经被持久化,但不再处于Session的缓存中。处于游离状态的Java对象被称为游离对象。

 

 

 

 

 

图为Java对象的完整状态转换图,Session的特定方法触发Java对象由一个状态转换到另一个状态。从图中看出,当Java 对象处于临时状态或游离状态,只要不被任何变量引用,就会结束生命周期,它占用的内存就可以被JVM的垃圾回收器回收;当处于持久化状态,由于 Session的缓存会引用它,因此它始终处于生命周期中。
 
 

 
临时对象特征


(1)
不处于Session的缓存中,也可以说,不被任何一个Session实例关联。
(2)
在数据库中没有对应的记录。

  
在以下情况下,Java对象进入临时状态:

(1)
当通过new语句刚创建一个Java对象,它处于临时状态,此时不和数据库中的任何记录对应
(2) Session
delete()方法能使一个持久化对象或游离对象转变为临时对象。对于游离对象,delete()方法从数据库中删除与它对应的记录; 对于持久化对象,delete()方法从数据库中删除与它对应的记录,并且把它从Session的缓存中删除。

 

 持久化对象的特征
 

(1)
位于一个Session实例的缓存中,也可以说,持久化对象总是被一个Session实例关联。
(2)
持久化对象和数据库中的相关记录对应。
(3) Session
在清理缓存时,会根据持久化对象的属性变化,来同步更新数据库。

Session
的许多方法都能够触发Java对象进入持久化状态:
(1) Session
save()方法把临时对象转变为持久化对象。
(2) Session
load()get()方法返回的对象总是处于持久化状态。
(3) Session
find()方法返回的List集合中存放的都是持久化对象。
(4) Session
update()saveOrUpdate()lock()方法使游离对象转变为持久化对象。
(5)
当一个持久化对象关联一个临时对象,在允许级联保存的情况下,Session在清理缓存时会把这个临时对象也转变为持久化对象。

Hibernate
保证在同一个Session实例的缓存中,数据库表中的每条记录只对应惟一的持久化对象。例如对于以下代码,共创建了两个 Session实例:session1session2session1session2拥有各自的缓存。在session1的缓存中,只会有惟一 的OID1Customer持久化对象,在session2的缓存中,也只会有惟一的OID1Customer持久化对象。因此在内存中共有两个 Customer持久化对象,一个属于session1的缓存,一个属于session2的缓存。引用变量ab都引用session1缓存中的 Customer持久化对象,而引用变量c引用session2缓存中的Customer持久化对象:

 

 

Session session1=sessionFactory.openSession();
 Session session2=sessionFactory.openSession();
 Transaction tx1 = session1.beginTransaction();
 Transaction tx2 = session2.beginTransaction();

 

Customer a=(Customer)session1.load(Customer.class,new Long(1)); 
Customer b=(Customer)session1.load(Customer.class,new Long(1)); 
Customer c=(Customer)session2.load(Customer.class,new Long(1)); 

 

System.out.println(a= =b); //true
System.out.println(a= =c); //false

 

tx1.commit();
tx2.commit();
session1.close();
session2.close();

 
 
Java
对象的持久化状态是相对于某个具体的Session实例的,以下代码试图使一个Java对象同时被两个Session实例关联:
 

Session session1=sessionFactory.openSession();
Session session2=sessionFactory.openSession();
Transaction tx1 = session1.beginTransaction();
Transaction tx2 = session2.beginTransaction();

 

Customer c=(Customer)session1.load(Customer.class,new Long(1)); //Customer对象被session1关联
session2.update(c); //Customer对象被session2关联
c.setName("Jack"); //修改Customer对象的属性

 

tx1.commit(); //执行update语句
tx2.commit(); //执行update语句
session1.close();
session2.close();

 

 

当执行session1load()方法时,OID1Customer对象被加入到session1的缓存中,因此它是 session1的持久化对象,此时它还没有被session2关联,因此相对于session2,它处于游离状态。当执行session2 update()方法时,Customer对象被加入到session2的缓存中,因此也成为session2的持久化对象。接下来修改Customer 对象的name属性,会导致两个Session实例在清理各自的缓存时,都执行相同的update语句:

update CUSTOMERS set NAME='Jack' …… where ID=1;


在实际应用程序中,应该避免一个Java对象同时被多个Session实例关联,因为这会导致重复执行SQL语句,并且极容易出现一些并发问题。

 游离对象的特征
 

(1)
不再位于Session的缓存中,也可以说,游离对象不被Session关联。
(2)
游离对象是由持久化对象转变过来的,因此在数据库中可能还存在与它对应的记录(前提条件是没有其他程序删除了这条记录)。

游离对象与临时对象的相同之处在于,两者都不被Session关联,因此Hibernate不会保证它们的属性变化与数据库保持同步。游离对象与临时对象的区别在于:前者是由持久化对象转变过来的,因此可能在数据库中还存在对应的记录,而后者在数据库中没有对应的记录。

Session
的以下方法使持久化对象转变为游离对象:
(1)
当调用Sessionclose()方法时,Session的缓存被清空,缓存中的所有持久化对象都变为游离对象。如果在应用程序中没有引用变量引用这些游离对象,它们就会结束生命周期。
(2)Session
evict()方法能够从缓存中删除一个持久化对象,使它变为游离状态。当Session的缓存中保存了大量的持久化对象,会消耗许多内存空间,为了提高性能,可以考虑调用evict()方法,从缓存中删除一些持久化对象。但是多数情况下不推荐使用evict()方法,而应该通过查询语言,或者显式的导航来控制对象图的深度。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值