
【引用】http://davidwei05951983.spaces.live.com/Blog/cns!BED3D557991594B3!812.entry
session的常用基本操作有:
Transient instances may be made persistent by calling save(),persist() or saveOrUpdate(). Persistent instances may be made transient by calling delete(). Any instance returned by a get() or load() method is persistent. Detached instances may be made persistent by calling update(), saveOrUpdate(), lock() or replicate(). The state of a transient or detached instance may also be made persistent as a new persistent instance by calling merge().save() and persist() result in an SQL INSERT, delete() in an SQL DELETE and update() or merge() in an SQL UPDATE. Changes to persistent instances are detected at flush time and also result in an SQL UPDATE. saveOrUpdate() and replicate() result in either an INSERT or an UPDATE.
persist():
Make a transient instance persistent. This operation cascades to associated instances if the association is mapped with cascade="persist". The semantics of this method are defined by JSR-220.
當(dāng)級(jí)聯(lián)風(fēng)格為persist時(shí),這個(gè)操作會(huì)級(jí)聯(lián)操作關(guān)聯(lián)的對(duì)象。這個(gè)方法的語義是JSR-220定義的。
persist() is well defined. It makes a transient instance persistent. However,
it doesn't guarantee that the identifier value will be assigned to the persistent
instance immediately, the assignment might happen at flush time. The spec doesn't say
that, which is the problem I have with persist().
persist() also guarantees that it will not execute an INSERT statement if it is
called outside of transaction boundaries. This is useful in long-running conversations
with an extended Session/persistence context.A method like persist() is required.
save() does not guarantee the same, it returns an identifier, and if an INSERT
has to be executed to get the identifier (e.g. "identity" generator, not "sequence"),
this INSERT happens immediately, no matter if you are inside or outside of a transaction. This is not good in a long-running conversation with an extended Session/persistence context."
save():
Persist the given transient instance, first assigning a generated identifier. (Or using the current value of the identifier property if the assigned generator is used.) This operation cascades to associated instances if the association is mapped with cascade="save-update".
首先會(huì)賦予一個(gè)標(biāo)志符,然后持久化給定的對(duì)象。但是如果使用assigned 標(biāo)志符產(chǎn)生方法,則會(huì)使用當(dāng)前的標(biāo)志符值。如果級(jí)聯(lián)風(fēng)格為save-pdate,則會(huì)持久化相應(yīng)的關(guān)聯(lián)對(duì)象.
merge():
Copy the state of the given object onto the persistent object with the same identifier. If there is no persistent instance currently associated with the session, it will be loaded. Return the persistent instance. If the given instance is unsaved, save a copy of and return it as a newly persistent instance. The given instance does not become associated with the session. This operation cascades to associated instances if the association is mapped with cascade="merge". The semantics of this method are defined by JSR-220.
拷貝當(dāng)前的對(duì)象的狀態(tài)到相同標(biāo)志符的持久化對(duì)象的狀態(tài)。如果當(dāng)前關(guān)聯(lián)的session中沒有持久化對(duì)象,Hibernate會(huì)加載該對(duì)象,并返回這個(gè)持久化對(duì)象。如果給定的對(duì)象沒有保存,則Hibernate保存該副本,返回這個(gè)新持久化的對(duì)象,但給定的對(duì)象并沒有和session關(guān)聯(lián)。如果指定級(jí)聯(lián)風(fēng)格為merge,則會(huì)級(jí)聯(lián)關(guān)聯(lián)對(duì)象。該方法的語義是JSR-200定義的。
saveOrUpdate():
Either {@link #save(String, Object)} or {@link #update(String, Object)} the given instance, depending upon resolution of the unsaved-value checks (see the manual for discussion of unsaved-value checking). This operation cascades to associated instances if the association is mapped with cascade="save-update".
保存或更新給定對(duì)象,取決于給定對(duì)象的持久化狀態(tài)。默認(rèn)情況下是保存,在指定標(biāo)志符元素屬性為unsaved-value時(shí)則會(huì)調(diào)整。如果級(jí)聯(lián)風(fēng)格為"save-update",則會(huì)級(jí)聯(lián)相關(guān)聯(lián)的對(duì)象
delete():
Remove a persistent instance from the datastore. The object argument may be an instance associated with the receiving Session or a transient instance with an identifier associated with existing persistent state. This operation cascades to associated instances if the association is mapped with cascade="delete".
刪除對(duì)象。
lock():
Obtain the specified lock level upon the given object. This may be used to perform a version check (LockMode.READ), to upgrade to a pessimistic lock (LockMode.UPGRADE), or to simply reassociate a transient instance with a session (LockMode.NONE). This operation cascades to associated instances if the association is mapped with cascade="lock".
用于對(duì)指定對(duì)象設(shè)置參數(shù)中給定的鎖。如果鎖為LockMode.READ,可以用來執(zhí)行版本檢查;如果鎖為LockMode.UPGRADE則用來執(zhí)行悲觀鎖。如果定為LockMode.NONE,則僅僅時(shí)持久化一個(gè)未持久化的對(duì)象。如果級(jí)聯(lián)風(fēng)格為lock,會(huì)級(jí)聯(lián)相關(guān)聯(lián)的對(duì)象。
refresh():
Re-read the state of the given instance from the underlying database. It is inadvisable to use this to implement long-running sessions that span many business tasks. This method is, however, useful in certain special circumstances.For example where a database trigger alters the object state upon insert or update after executing direct SQL (eg. a mass update) in the same session after inserting a Blob or Clob.
從當(dāng)前數(shù)據(jù)庫中重新讀取給定對(duì)象的狀態(tài)。這在執(zhí)行跨越多個(gè)業(yè)務(wù)任務(wù)的長時(shí)間session中優(yōu)勢(shì)不顯著,在少數(shù)特定環(huán)境下還是有用的,例如: 插入或更新后數(shù)據(jù)庫觸發(fā)器更改了對(duì)象的狀態(tài)。當(dāng)前session中執(zhí)行完原生SQL后(如批量更新)。 插入Blob或Clob對(duì)象后。
evict():
Remove this instance from the session cache. Changes to the instance will not be synchronized with the database. This operation cascades to associated instances if the association is mapped with cascade="evict".
從session的緩存中去除當(dāng)前實(shí)例。執(zhí)行后對(duì)象的改變將不再和數(shù)據(jù)庫保持同步。當(dāng)指定級(jí)聯(lián)風(fēng)格為'evict’時(shí),會(huì)級(jí)聯(lián)操作關(guān)聯(lián)對(duì)象。我用的時(shí)候主要是用于批量操作的時(shí)候,清空緩存,防止內(nèi)存緊張。
replicate():
Persist the state of the given detached instance, reusing the current identifier value. This operation cascades to associated instances if the association is mapped with cascade="replicate"
重用當(dāng)前的標(biāo)志符,持久化當(dāng)前已經(jīng)脫離session的對(duì)象的狀態(tài)。具體的操作和要看參數(shù)ReplicationMode。如果是ReplicationMode.EXCEPTION,則在復(fù)制時(shí)如果有重復(fù)的行數(shù)據(jù),則拋出異常。ReplicationMode.IGNORE則忽略異常。ReplicationMode.OVERWRITE則會(huì)覆蓋掉已有行數(shù)據(jù)。ReplicationMode.LATEST_VERSION則是在有重復(fù)時(shí)使用最新的版本進(jìn)行控制。
自動(dòng)狀態(tài)檢測(cè)
Hibernate的用戶曾要求一個(gè)既可自動(dòng)分配新持久化標(biāo)識(shí)(identifier)保存瞬時(shí)(transient)對(duì)象,又可更新/重新關(guān)聯(lián)脫管(detached)實(shí)例的通用方法。 saveOrUpdate()方法實(shí)現(xiàn)了這個(gè)功能。 saveOrUpdate()用途和語義可能會(huì)使新用戶感到迷惑。 首先,只要你沒有嘗試在某個(gè)session中使用來自另一session的實(shí)例,你就應(yīng)該不需要使用update(), saveOrUpdate(),或merge()。有些程序從來不用些方法。
通常下面的場(chǎng)景會(huì)使用update()或saveOrUpdate():
程序在第一個(gè)session中加載對(duì)象
該對(duì)象被傳遞到表現(xiàn)層
對(duì)象發(fā)生了一些改動(dòng)
該對(duì)象被返回到業(yè)務(wù)邏輯層
程序調(diào)用第二個(gè)session的update()方法持久這些改動(dòng)
saveOrUpdate()做下面的事:
如果對(duì)象已經(jīng)在本session中持久化了,不做任何事
如果另一個(gè)與本session關(guān)聯(lián)的對(duì)象擁有相同的持久化標(biāo)識(shí)(identifier),拋出一個(gè)異常
如果對(duì)象沒有持久化標(biāo)識(shí)(identifier)屬性,對(duì)其調(diào)用save()
如果對(duì)象的持久標(biāo)識(shí)(identifier)表明其是一個(gè)新實(shí)例化的對(duì)象,對(duì)其調(diào)用save()
如果對(duì)象是附帶版本信息的(通過<version>或<timestamp>) 并且版本屬性的值表明其是一個(gè)新實(shí)例化的對(duì)象,save()它。
否則update() 這個(gè)對(duì)象
merge()可非常不同:
如果session中存在相同持久化標(biāo)識(shí)(identifier)的實(shí)例,用用戶給出的對(duì)象的狀態(tài)覆蓋舊有的持久實(shí)例
如果session沒有相應(yīng)的持久實(shí)例,則嘗試從數(shù)據(jù)庫中加載,或創(chuàng)建新的持久化實(shí)例 ,最后返回該持久實(shí)例
用戶給出的這個(gè)對(duì)象沒有被關(guān)聯(lián)到session上,它依舊是脫管的.
Session刷出(flush)
每間隔一段時(shí)間,Session會(huì)執(zhí)行一些必需的SQL語句來把內(nèi)存中的對(duì)象的狀態(tài)同步到JDBC連接中。這個(gè)過程被稱為刷出(flush),默認(rèn)會(huì)在下面的時(shí)間點(diǎn)執(zhí)行:
a.在某些查詢執(zhí)行之前
b.在調(diào)用org.hibernate.Transaction.commit()的時(shí)候
c.在調(diào)用Session.flush()的時(shí)候
涉及的SQL語句會(huì)按照下面的順序發(fā)出執(zhí)行:
所有對(duì)實(shí)體進(jìn)行插入的語句,其順序按照對(duì)象執(zhí)行Session.save()的時(shí)間順序
所有對(duì)實(shí)體進(jìn)行更新的語句
所有進(jìn)行集合刪除的語句
所有對(duì)集合元素進(jìn)行刪除,更新或者插入的語句
所有進(jìn)行集合插入的語句
所有對(duì)實(shí)體進(jìn)行刪除的語句,其順序按照對(duì)象執(zhí)行Session.delete()的時(shí)間順序
(有一個(gè)例外是,如果對(duì)象使用native方式來生成ID(持久化標(biāo)識(shí))的話,它們一執(zhí)行save就會(huì)被插入。)
除非你明確地發(fā)出了flush()指令,關(guān)于Session何時(shí)會(huì)執(zhí)行這些JDBC調(diào)用是完全無法保證的,只能保證它們執(zhí)行的前后順序。 當(dāng)然,Hibernate保證,Query.list(..)絕對(duì)不會(huì)返回已經(jīng)失效的數(shù)據(jù),也不會(huì)返回錯(cuò)誤數(shù)據(jù)。
也可以改變默認(rèn)的設(shè)置,來讓刷出(flush)操作發(fā)生的不那么頻繁。 FlushMode類定義了三種不同的方式。 僅在提交時(shí)刷出(僅當(dāng)Hibernate的Transaction API被使用時(shí)有效), 按照剛才說的方式刷出, 以及除非明確使用flush()否則從不刷出。 最后一種模式對(duì)于那些需要長時(shí)間保持Session為打開或者斷線狀態(tài)的長時(shí)間運(yùn)行的工作單元很有用。
父子關(guān)系的級(jí)聯(lián)(cascading)操作準(zhǔn)確語義如下:
如果父對(duì)象被persist(),那么所有子對(duì)象也會(huì)被persist()
如果父對(duì)象被merge(),那么所有子對(duì)象也會(huì)被merge()
如果父對(duì)象被save(),update()或 saveOrUpdate(),那么所有子對(duì)象則會(huì)被saveOrUpdate()
如果某個(gè)持久的父對(duì)象引用了瞬時(shí)(transient)或者脫管(detached)的子對(duì)象,那么子對(duì)象將會(huì)被saveOrUpdate()
如果父對(duì)象被刪除,那么所有子對(duì)象也會(huì)被delete()
除非被標(biāo)記為cascade="delete-orphan"(刪除“孤兒”模式,此時(shí)不被任何一個(gè)父對(duì)象引用的子對(duì)象會(huì)被刪除), 否則子對(duì)象失掉父對(duì)象對(duì)其的引用時(shí),什么事也不會(huì)發(fā)生。 如果有特殊需要,應(yīng)用程序可通過顯式調(diào)用delete()刪除子對(duì)象。