關於Session介面的update方法主要有如下幾點要注意:
1.輸入參數
一般而言,傳遞給update的對象要是處於游離狀態的對象。如果傳一個持久化對象,那麼update方法就是多餘的,因為Hibernate的髒檢查機制會自動根據對象屬性值的變化向資料庫發送一條update語句;如果傳入的對象處於臨時狀態,那麼此時Hibernate應該會拋出異常。因為Hibernate在更新資料時會根據對象的OID去資料庫尋找相應的記錄並更新之,而在資料庫中是沒有記錄與這個臨時對象相關聯的,因此Hibernate會拋出異常,當然如果你人為的給臨時對象指定一個OID就該另當別論了,如下所示程式碼片段:
…………………………………………
Customer customer=new Customer();
customer.setId(3L);
customer.setName(“Cindyelf”);
session.update(customer);
…………………………………………
這段代碼會導致如下的sql:update Customer set name=’Cindyelf’ where id=3;當然如果資料庫不存在id為3的那行記錄,Hibernate就會拋出異常。而給臨時對象指定OID是不合規範的操作,應盡量避免。也就是說不管傳入是什麼狀態物件,資料庫中必須要有一條記錄與這個對象的OID相對應,否則拋出異常。
2.操作
執行update方法的時候,Hibernate會首先把傳入的對象放入Session的緩衝中,使之持久化,然後計劃執行一個update語句。Hibernate在產生sql語句的時候會根據對象的當前屬性值來組裝sql語句,也就是說,不管程式中修改了多少次屬性值,在執行時只會執行一條update一句。
此外,在update的官方API中特意強調了一點,“如果在session的緩衝中有一個持久化對象和所要更新的對象具有相同的OID,那麼Hibernate會拋出異常”。下面的程式碼片段示範了這個錯誤:
…………………………………………
Customer customer=new Customer();
session1.save(customer);
…………………………………………
…………………………………………
Customer customer1=(Customer)session.load(Customer.class,new Long(6))
session2.update(customer);
…………………………………………
如上所示,我在session1中持久化了一個Customer對象,它的OID是6,然後我在session2中load一個OID為6的對象customer1,然後在session2中update之前的customer,注意,對於session2而已,customer1是處於游離狀態的,因為它不處於session2的緩衝中。此時程式會報如下錯誤:a different object with the same identifier value was already associated with the session。