Hibernate中的session對象update方法的使用


使一個游離對象轉變為持久化對象。例如以下代碼在session1中保存了一個Customer對象,然后在session2中更新這個Customer對象:

Customer customer = new Customer();

customer.setName("Tom");

Session session1 = sessionFactory.buildSession();

Transaction tx1 = session.beginTransaction();

session1.save(customer);

tx1.commit();

session1.close();

 

Session session2 = sessionFactory.openSession();

Transaction tx2 = session2.beginTransaction();

customer.setName("Linda"); // 在和session2關聯之前修改Customer對象的屬性

session2.update(customer);

customer2.setName("Jack"); // 在和session2關聯之后修改Customer對象的屬性

tx2.commit();

session2.close();

Session的update()方法完成以下操作:

(1)把Customer對象重新加入到Session的緩存中,使它變為持久化對象。

(2)計划執行一個update語句。值得注意的是,Session只有在清理緩存的時候才會執行update語句,並且在執行時才會把Customer對象當前的屬性值組裝到update語句中。因此,即使程序中多次修改了Customer對象的屬性,在清理緩存時只會執行一次update語句。以下兩段代碼是等價的,無論是左邊的代碼,還是右邊的代碼,Session都只會執行一條update語句:

 

......

Session session2 = sessionFactory.openSession();

Transaction tx2 = session2.beginTransaction();

customer2.setName("Linda");

session.update(customer);

customer.setName("Jack");

tx2.commit();

session2.close();

......

Session session2 = sessionFactory.openSession();

Transaction tx2 = session1.beginTransaction();

session2.update(customer);

customer.setName("Linda");

customer.setName("Jack");

txt2.commit();

session2.close();

 

以上代碼盡管把Customer對象的name屬性修改了兩次,但Session在清理緩存時,根據Customer對象的當前屬性值來組裝update語句,因此執行的update語句為:

update CUSTOMERS set name='Jack' ...... where ID=1;

只要通過update()方法使游離對象被一個Session關聯,即使沒有修改Customer對象的任何屬性,Session在清理緩存時也會執行由update()方法計划的update語句。例如以下程序使Customer對象被session2關聯,但是沒有修改Customer對象的任何屬性:

// 此處省略session1持久化Customer對象的代碼

Session session2 = sessionFactory.openSession();

Transaction tx2 = session2.beginTransaction();

session.update(customer);

txt2.commit();

session2.close();

Session在清理存緩時,會執行由update()方法計划的update語句,並且根據Customer對象的當前屬性來組裝update語句:

update CUSTOMERS set name='Tom' ...... where ID=1;

如果希望Session僅僅當修改了Customer對象的屬性時,才執行update語句,可以把映射文件中<class>元素的select-before-update設為true,該屬性默認值為false:

<class name="Customer" table="CUSTOMERS" selecet-before-update="true">

  如果按以上方式修改了Customer.hbm.xml文件,當Session清理緩存時,會先執行一條select語句:

select * from CUSTOMERS where ID=1;

然后比較Customer對象的屬性是否和從數據庫中檢索出來的記錄一致,只有在不一致的情況下,才執行update語句。

應用根據實際情況來決定是否應該把select-before-update設為true。如果Java對象的屬性不會經常變化,可以把select-before-update屬性設為true,避免Session執行不必要的update語句,這樣會提高應用程序的性能。如果需要經常修改Java對象的屬性,就沒必要把這個屬性設為true,因為它會導致在執行update語句之前,執行一條多余的select語句。

當update()方法關聯一個游離對象時,如果在Session的緩存中已經存在相同OID的持久化對象,會拋出異常。例如以下代碼通過session2加載了OID為1的Customer對象,接下來又試圖把一個OID為1的Customer游離對象加入到session2的緩存中:

// 此處省略session1持久化Customer對象的代碼

......

Session session2 = sessionFactory.openSession();

Transaction tx2 = session2.beginTransaction();

// session2加載一個OID為1的Customer持久化對象

Customer anotherCustomer = (Customer)session2.load(Customer.class, new Long(1));

// 把一個OID為1的Customer游離對象加入到session2的緩存中

session2.update(customer);

tx2.commit();

session2.close();

當執行session2的update()方法時,由於session2的緩存中已經存在了OID為1的Customer持久化對象,因此不允許把OID為1的Customer游離對象再加入到session2的緩存中,Session在運行時會拋出異常。此外,當update()方法關聯一個游離對象時,如果在數據庫中不存在相應的記錄,也會拋出異常。

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM