<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.tkk7.com/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>