04_傳智播客hibernate教程_Session接口及getloadpersist方法 2

Hibernate users have requested a general purpose method that either saves a transient instance

by generating a new identifier or updates/reattaches the detached instances associated with its

current identifier. The saveOrUpdate() method implements this functionality.

// in the first session

Cat cat = (Cat) firstSession.load(Cat.class, catID);

// in a higher tier of the application

Cat mate = new Cat();

cat.setMate(mate);

// later, in a new session

secondSession.saveOrUpdate(cat); // update existing state (cat has a non-null id)

secondSession.saveOrUpdate(mate); // save the new instance (mate has a null id)

瞬時對象,遊離對象通過saveOrUpdate方法轉變成持久對象

  1 瞬時對象 執行save

  2 遊離對象 執行Update

在你無法確定這個對象的狀態時候,應用此方法

The usage and semantics of saveOrUpdate() seems to be confusing for new users. Firstly, so

long as you are not trying to use instances from one session in another new session, you should not need to use update(), saveOrUpdate(), or merge(). Some whole applications will never use either of these methods.

如果 需要一個的對象先後出現在不同的session中,需要調用update(), saveOrUpdate(), or merge()

Usually update() or saveOrUpdate() are used in the following scenario:

• the application loads an object in the first session

• the object is passed up to the UI tier

• some modifications are made to the object

• the object is passed back down to the business logic tier

• the application persists these modifications by calling update() in a second session

saveOrUpdate() does the following:

• if the object is already persistent in this session, do nothing

 (因爲hibernate 可以自動檢測持久對象的狀態,並持久到數據庫中去(事務提交時),所以是do nothing)

• if another object associated with the session has the same identifier, throw an exception

 (記住這個saveOrUpdate方法拋出的異常

• if the object has no identifier property, save() it(如果是臨時對象)

• if the object's identifier has the value assigned to a newly instantiated object, save() it

• if the object is versioned by a <version> or <timestamp>, and the version property value is the same value assigned to a newly instantiated object, save() it

(如果object's identifier的值與配置文件中設定的unsaved-value相同 插入新的數據 實際上顯式的使用session.save()或者session.update()操作一個對象的時候,實際上是用不到unsaved-value

• otherwise update() the object

 

and merge() is very different:

• if there is a persistent instance with the same identifier currently associated with the session,

copy the state of the given object onto the persistent instance

• if there is no persistent instance currently associated with the session, try to load it from the

database, or create a new persistent instance

• the persistent instance is returned

• the given instance does not become associated with the session, it remains detached

 

如果session中存在相同持久化標識(identifier)的實例,用用戶給出的對象的狀態覆蓋舊有的持久實例

如果session沒有相應的持久實例,則嘗試從數據庫中加載,或創建新的持久化實例,最後返回該持久實例

用戶給出的這個對象沒有被關聯到session上,它依舊是脫管的

重點是最後一句:

當我們使用update的時候,執行完成後,我們提供的對象A的狀態變成持久化狀態

但當我們使用merge的時候,執行完成,我們提供的對象A還是脫管狀態,hibernate或者new了一個B,或者檢索到

一個持久對象B,並把我們提供的對象A的所有的值拷貝到這個B,執行完成後B是持久狀態,而我們提供的A還是託管狀

 

不贊成使用此方法(這個方法的註釋上這麼說的

@deprecated use {@link org.hibernate.Session#merge(String, Object)}

 

 

小結

1 顯式的使用session.save()或者session.update()操作一個對象的時候,

實際上是用不到unsaved-value

2 即使你對臨時對象id進行了設置,hibernate也會根據

配置文件設定的主建策略,生成主鍵,並覆蓋程序員設定的值

3 如果你修改了遊離對象的id 兩種結果一種 拋出org.hibernate.StaleStateException

更新一條不存在的數據拋出異常

另一種更新了修改後id對於那個的記錄

4 只有在調用saveOrUpdate方法時 unsaved-value 的配置值先判斷是不是save

如果不是save那麼就是updade()

5 StaleStateException Thrown when a version number or timestamp check failed, indicating

that the Session contained stale data (when using long transactions

with versioning). Also occurs if we try delete or update a row that

does not exist.

Note that this exception often indicates that the user failed to

specify the correct unsaved-value strategy for a class!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章