【引用】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.
    當級聯風格為persist時,這個操作會級聯操作關聯的對象。這個方法的語義是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".
    首先會賦予一個標志符,然后持久化給定的對象。但是如果使用assigned 標志符產生方法,則會使用當前的標志符值。如果級聯風格為save-pdate,則會持久化相應的關聯對象.

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.
    拷貝當前的對象的狀態到相同標志符的持久化對象的狀態。如果當前關聯的session中沒有持久化對象,Hibernate會加載該對象,并返回這個持久化對象。如果給定的對象沒有保存,則Hibernate保存該副本,返回這個新持久化的對象,但給定的對象并沒有和session關聯。如果指定級聯風格為merge,則會級聯關聯對象。該方法的語義是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".
    保存或更新給定對象,取決于給定對象的持久化狀態。默認情況下是保存,在指定標志符元素屬性為unsaved-value時則會調整。如果級聯風格為"save-update",則會級聯相關聯的對象

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".
    刪除對象。

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".
    用于對指定對象設置參數中給定的鎖。如果鎖為LockMode.READ,可以用來執行版本檢查;如果鎖為LockMode.UPGRADE則用來執行悲觀鎖。如果定為LockMode.NONE,則僅僅時持久化一個未持久化的對象。如果級聯風格為lock,會級聯相關聯的對象。

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.
    從當前數據庫中重新讀取給定對象的狀態。這在執行跨越多個業務任務的長時間session中優勢不顯著,在少數特定環境下還是有用的,例如: 插入或更新后數據庫觸發器更改了對象的狀態。當前session中執行完原生SQL后(如批量更新)。 插入Blob或Clob對象后。
 
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的緩存中去除當前實例。執行后對象的改變將不再和數據庫保持同步。當指定級聯風格為'evict’時,會級聯操作關聯對象。我用的時候主要是用于批量操作的時候,清空緩存,防止內存緊張。

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"
    重用當前的標志符,持久化當前已經脫離session的對象的狀態。具體的操作和要看參數ReplicationMode。如果是ReplicationMode.EXCEPTION,則在復制時如果有重復的行數據,則拋出異常。ReplicationMode.IGNORE則忽略異常。ReplicationMode.OVERWRITE則會覆蓋掉已有行數據。ReplicationMode.LATEST_VERSION則是在有重復時使用最新的版本進行控制。





自動狀態檢測

 

    Hibernate的用戶曾要求一個既可自動分配新持久化標識(identifier)保存瞬時(transient)對象,又可更新/重新關聯脫管(detached)實例的通用方法。 saveOrUpdate()方法實現了這個功能。 saveOrUpdate()用途和語義可能會使新用戶感到迷惑。 首先,只要你沒有嘗試在某個session中使用來自另一session的實例,你就應該不需要使用update(), saveOrUpdate(),或merge()。有些程序從來不用些方法。

通常下面的場景會使用update()或saveOrUpdate():
程序在第一個session中加載對象
該對象被傳遞到表現層
對象發生了一些改動
該對象被返回到業務邏輯層
程序調用第二個session的update()方法持久這些改動

saveOrUpdate()做下面的事:
如果對象已經在本session中持久化了,不做任何事
如果另一個與本session關聯的對象擁有相同的持久化標識(identifier),拋出一個異常
如果對象沒有持久化標識(identifier)屬性,對其調用save()
如果對象的持久標識(identifier)表明其是一個新實例化的對象,對其調用save()
如果對象是附帶版本信息的(通過<version>或<timestamp>) 并且版本屬性的值表明其是一個新實例化的對象,save()它。
否則update() 這個對象

merge()可非常不同:
如果session中存在相同持久化標識(identifier)的實例,用用戶給出的對象的狀態覆蓋舊有的持久實例
如果session沒有相應的持久實例,則嘗試從數據庫中加載,或創建新的持久化實例 ,最后返回該持久實例
用戶給出的這個對象沒有被關聯到session上,它依舊是脫管的.


Session刷出(flush)
每間隔一段時間,Session會執行一些必需的SQL語句來把內存中的對象的狀態同步到JDBC連接中。這個過程被稱為刷出(flush),默認會在下面的時間點執行:
a.在某些查詢執行之前
b.在調用org.hibernate.Transaction.commit()的時候
c.在調用Session.flush()的時候

涉及的SQL語句會按照下面的順序發出執行:
所有對實體進行插入的語句,其順序按照對象執行Session.save()的時間順序
所有對實體進行更新的語句
所有進行集合刪除的語句
所有對集合元素進行刪除,更新或者插入的語句
所有進行集合插入的語句
所有對實體進行刪除的語句,其順序按照對象執行Session.delete()的時間順序

(有一個例外是,如果對象使用native方式來生成ID(持久化標識)的話,它們一執行save就會被插入。)
除非你明確地發出了flush()指令,關于Session何時會執行這些JDBC調用是完全無法保證的,只能保證它們執行的前后順序。 當然,Hibernate保證,Query.list(..)絕對不會返回已經失效的數據,也不會返回錯誤數據。

也可以改變默認的設置,來讓刷出(flush)操作發生的不那么頻繁。 FlushMode類定義了三種不同的方式。 僅在提交時刷出(僅當Hibernate的Transaction API被使用時有效), 按照剛才說的方式刷出, 以及除非明確使用flush()否則從不刷出。 最后一種模式對于那些需要長時間保持Session為打開或者斷線狀態的長時間運行的工作單元很有用。


父子關系的級聯(cascading)操作準確語義如下:
如果父對象被persist(),那么所有子對象也會被persist()
如果父對象被merge(),那么所有子對象也會被merge()
如果父對象被save(),update()或 saveOrUpdate(),那么所有子對象則會被saveOrUpdate()
如果某個持久的父對象引用了瞬時(transient)或者脫管(detached)的子對象,那么子對象將會被saveOrUpdate()
如果父對象被刪除,那么所有子對象也會被delete()

除非被標記為cascade="delete-orphan"(刪除“孤兒”模式,此時不被任何一個父對象引用的子對象會被刪除), 否則子對象失掉父對象對其的引用時,什么事也不會發生。 如果有特殊需要,應用程序可通過顯式調用delete()刪除子對象。