2011-08-18 80 views
2

我需要在事務中保存兩次相同的對象,但是休眠總是隻有一次sql更新,有辦法嗎? 下面是代碼:休眠:需要在事務內保存兩次相同的對象

.... 
session.beginTransaction(); 
Student s = session.get(Student.class, id); 

// (1) first save 
s.setSequenceNum(10); 
session.saveOrUpdate(s); 

// (2) second save 
s.setSequenceNum(9); 
session.saveOrUpdate(s); // save again 

session.getTransaction().commit(); 
session.close(); 

Hibernate會忽略第一個,也是唯一擁有第二個SQL更新。我怎麼讓休眠做兩個SQL更新?我需要這個,因爲這是我們項目的要求。

+0

你怎麼知道它忽略了第一個,只更新了第二個?由於只查看數據庫,你不能發現它忽略了你的第一個請求...... –

+0

在任何情況下,這是多餘的,因爲第二次更新會覆蓋第一次。我可以看到這個唯一的原因,如果有某種數據庫觸發器必須執行 –

+0

爲什麼你想要兩個更新? –

回答

4

在第一次更新之後嘗試session.flush(),或在第一次更新之前設置session.setFlushMode(FlushMode.Always)。請記住,setFlushmode會影響整個會話,如果它在交易後被重新使用

+0

謝謝,它可以解決我的問題,還有一個問題,如果我設置session.setFlushMode(FlushMode.Always),這會影響性能嗎?我的意思是它會變慢或不變。 – hebing

+0

http://docs.jboss.org/hibernate/core/3.5/javadocs/org/hibernate/FlushMode.html 你會對db執行更多的sql查詢,所以它可能會更慢。 –

9

saveOrUpdate對於連接的實例是完全不必要的。 Hibernate將在交易結束時自動持續附帶的對象

  • 的狀態
  • 執行一個查詢的結果調用flush時可能取決於對象
  • 的新狀態明確地在會話時

附加對象是從會話中檢索到的對象(從調用中獲取,加載或從查詢中獲取),或者通過持久化,保存,更新或合併(在這後一種情況下,傳遞的對象不附加,但是返回的對象是)。

那麼爲什麼saveOrUpdate有用?將臨時或分離對象作爲持久對象,即未附加到會話的對象,或者是因爲它是新的對象,或者是因爲它是先前附加的,而是在會話關閉時分離出來的,對此非常有用。

Hibernate的想法是隻在最有可能的時候刷新修改後的狀態(即執行更新SQL查詢)。這樣,它可以避免不必要的更新,從而使代碼更有效率。您的第一次更新是不必要的,除非您在兩次更新之間的同一事務中執行本機SQL查詢。你爲什麼要中間狀態被持續?

+0

+1。非常感謝你解釋我必須解釋什麼... –

+0

是的,這是真的,我確實需要第一次更新,因爲db在列「sequence_num」上有一個唯一索引,那裏已經有「1, 2,... 8,9「,我想交換8和9.所以我做的是:1)8 - > 10,2)9 - > 8,3)10 - > 9 – hebing

+0

啊,好的。然後,只要您設置了新值,請刷新會話。不需要saveOrUpdate。更簡單的方法是將此約束定義爲延遲約束。延遲約束僅在事務結束時檢查,而不是每次設置新值時檢查。 –