<p>1)与Java对象在JVM中的生命周期类似,Java对象在Hibernate的session中也有生命周期类似的状态。在Hibernate的session中,对象有3种状态:临时状态,持久化状态,游离状态。<br />
a. 临时状态(transient),刚new出来的对象,还没有被session持久化,不处于session的缓存中<br />
b.持久化状态(persistent),已经被持久化(在数据库中有相应的记录),并且存在于session的缓存中<br />
c. 游离状态(detached),已经被持久化(在数据库中可能存在也可能不存在相应的记录),不存在于session的缓存中<br />
<br />
简单的用个例子描述一下:<br />
</p>
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><span style="color: #008080"> 1</span><img alt="" src="/Images/OutliningIndicators/None.gif" align="top" /><span style="color: #000000"><img alt="" src="http://www.blogjava.net/Images/dot.gif" /><br />
</span><span style="color: #008080"> 2</span><span style="color: #000000"><img alt="" src="/Images/OutliningIndicators/None.gif" align="top" />tx </span><span style="color: #000000">=</span><span style="color: #000000"> session.beginTransaction();<br />
</span><span style="color: #008080"> 3</span><span style="color: #000000"><img alt="" src="/Images/OutliningIndicators/None.gif" align="top" />Customer c1 </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #0000ff">new</span><span style="color: #000000"> Customer(</span><span style="color: #000000">"</span><span style="color: #000000">Tom</span><span style="color: #000000">"</span><span style="color: #000000">,</span><span style="color: #0000ff">new</span><span style="color: #000000"> HashSet()); //c1 处于临时状态<br />
</span><span style="color: #008080"> 4</span><span style="color: #000000"><img alt="" src="/Images/OutliningIndicators/None.gif" align="top" />session.save(c1); //c1转换为持久化状态<br />
</span><span style="color: #008080"> 5</span><span style="color: #000000"><img alt="" src="/Images/OutliningIndicators/None.gif" align="top" />Long id </span><span style="color: #000000">=</span><span style="color: #000000"> c1.getId();<br />
</span><span style="color: #008080"> 6</span><span style="color: #000000"><img alt="" src="/Images/OutliningIndicators/None.gif" align="top" />c1 </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #0000ff">null</span><span style="color: #000000">;<br />
</span><span style="color: #008080"> 7</span><span style="color: #000000"><img alt="" src="/Images/OutliningIndicators/None.gif" align="top" />Customer c2 </span><span style="color: #000000">=</span><span style="color: #000000"> (Customer)session.load(Customer.</span><span style="color: #0000ff">class</span><span style="color: #000000">,id); //c2 处于持久化状态<br />
</span><span style="color: #008080"> 8</span><span style="color: #000000"><img alt="" src="/Images/OutliningIndicators/None.gif" align="top" />tx.commit();<br />
</span><span style="color: #008080"> 9</span><span style="color: #000000"><img alt="" src="/Images/OutliningIndicators/None.gif" align="top" />session.close(); //c1转换为游离状态 <br />
</span><span style="color: #008080">10</span><span style="color: #000000"><img alt="" src="/Images/OutliningIndicators/None.gif" align="top" />c2 </span><span style="color: #000000">=</span><span style="color: #000000"> </span><span style="color: #0000ff">null</span><span style="color: #000000">; //c2转换为游离状态</span></div>
<br />
<br />
<br />
2)对象的状态转换<br />
<img height="277" alt="" src="/images/blogjava_net/ericzhang5231/StateTransform.jpg" width="398" border="0" /><br />
<br />
<table style="width: 1000px; height: 195px" cellspacing="2" cellpadding="2" width="1000" border="0">
<tbody>
<tr>
<td>状态名称</td>
<td>状态特征</td>
<td>进入条件</td>
<td>备注</td>
</tr>
<tr>
<td>临时对象</td>
<td>
<p>1.不存在任何一个session;</p>
<p>2.在数据库没有相应的记录;</p>
</td>
<td>
<p>1. 通过new;</p>
<p>2.Session通过delete()把持久化对象和游离对象转化为临时对象</p>
</td>
<td></td>
</tr>
<tr>
<td>持久化对象</td>
<td>
<p>1.总是被一个Session对象关联;</p>
<p>2.在数据库有相应的记录;<br />
3.session清理缓存的时候,会根据持久化对象的属性变化(其实根据快照),来同步更新数据库</p>
</td>
<td>
<p>1.session的save()把临时对象转化持久化对象;<br />
2.session的load()或get()返回的对象;<br />
3.session的find()返回的对象;<br />
4.session的update(),saveOrUpdate()和lock()使游离对象转变为持久化对象;<br />
5.当一个持久化对象关联一个临时对象,当允许级联保存的情况下,临时对象也转化为持久化对象;</p>
<p> </p>
</td>
<td>1.避免多个session实例关联一个Java对象</td>
</tr>
<tr>
<td>游离对象 </td>
<td>
<p>1.不被session关联;</p>
<p>2.游离对象是由持久化对象转化过来的,数据库中可能存在也可能不存在相应的记录;</p>
</td>
<td>
<p>1.session的close(),把缓存中的所有持久化对象都转变为游离对象;</p>
<p>2.session的evict(),把缓存中的一个持久化对象删除,使它变成游离状态;</p>
</td>
<td>1.游离对象和临时对象的区别在于数据库是否存在相应的记录</td>
</tr>
</tbody>
</table>
<br />
<br />
<br />
3)Session的缓存以及API<br />
1.Session:在Session接口的实现类SessionImpl中定义了一系列的Java集合,这些集合构成了Sessiond缓存<br />
2.API:<br />
<table style="width: 1005px; height: 270px" cellspacing="2" cellpadding="2" width="1005" border="0">
<tbody>
<tr>
<td>save()</td>
<td>
<p>1.在save一个临时对象之前,设置对象的主键ID,没效果;</p>
<p>2.在save一个对象之后,对象主键ID不能修改,否则抛异常;<br />
3.如果主键ID是用nactive方式生成的,一旦调用session的save方法,hibernate会立即向数据库插入数据;<br />
4.save用来持久化一个临时对象,若持久一个持久化对象,没效果,若持久一个游离对象,会重新插入数据;</p>
</td>
</tr>
<tr>
<td>update()</td>
<td>
<p>1.session清理缓存的时候,才会去执行update()产生的sql语句,因此即使程序多次修改对象属性,最后只会更新最后的修改;</p>
<p>2.通过update()使一个游离对象被一个session关联,即使没有修改对象属性,在清理缓存的时候也会执行update()产生sql语句<br />
(如果希望仅当修改对象属性才进行update,可在<class>元素的select-before-update设置为true);<br />
3.当update()方法关联一个游离对象,如果session中存在相同OID的持久化对象,会抛出异常;<br />
4.当update()方法关联一个游离对象,如果数据库中不存在相应记录,会抛出异常;</p>
</td>
</tr>
<tr>
<td>saveOrUpdate()</td>
<td>
<p>1.如果传入的是临时对象,调用save(); 如果传入的是持久化对象,调用update();</p>
</td>
</tr>
<tr>
<td>load(), get()</td>
<td>1.两者都是根据OID从数据库中加载持久化对象,区别是:当数据库不存在与OID对应的记录,load()会抛出net.sf.hibernate.ObjectNotFoundException,而get()方法返回null;</td>
</tr>
<tr>
<td>delete()</td>
<td>1.对传入的是持久化对象,session就按照预先的sql语句删除一个记录;如果是一个游离态对象,会把它关联到session,在按照sql语句删除记录</td>
</tr>
</tbody>
</table>
<br />
3.session的级联:因为对象是相互关联,因此在session存放的是一副相互关联的对象图。在对象-关联映射文件中,用于映射持久化类之间关联的元素,如<set>,<many-to-one>,<one-to-many>,都有一个cascade属性。casecade属性值如下:<br />
<table cellspacing="2" cellpadding="2" width="500" border="0">
<tbody>
<tr>
<td>属性值</td>
<td>描述</td>
</tr>
<tr>
<td>none</td>
<td>默认值,忽略关联对象</td>
</tr>
<tr>
<td>save-update</td>
<td>session对当前对象调用save(),update(),saveOrUpdate(),级联保存关联的临时对象,级联更新关联的游离对象</td>
</tr>
<tr>
<td>delete</td>
<td>级联删除所有关联的对象</td>
</tr>
<tr>
<td>all</td>
<td>包含save-update(),delelte()行为;当对当前对象执行evict()或lock(),级联执行关联的对象</td>
</tr>
<tr>
<td>delete-orphan</td>
<td>删除所有和当前对象解除关联关系的对象</td>
</tr>
<tr>
<td>all-delete-orphan</td>
<td>包含all和delete-orphan的行为</td>
</tr>
</tbody>
</table>