2011-04-08 71 views
2

爲什麼hibernate在保存對象前做了select?爲什麼hibernate在保存之前執行SELECT?

我在互聯網上找不到有用的信息。這是每次保存前的正常行爲嗎?我發現這個主題,select Query Run for hibernateTemplate.save() - 保存,但我沒有找到這個答案「權威」。我的意思是,如果我想在保存每個對象之前避免這種選擇,我們是否必須使用版本控制?

我將不勝感激所有的解釋或鏈接。

+0

您是如何在映射中添加版本列的?請提供來源。 – cherouvim 2011-04-08 06:33:55

+0

@cherouvim:我已經添加了列以防止此選擇。這就是: \t Julia 2011-04-08 06:47:36

+0

您能否顯示部分選擇聲明? – cherouvim 2011-04-08 07:21:38

回答

1

我知道你已經在問題的評論中回答了你自己的問題,但只是爲了總結這裏的一些一般觀點。

只是爲了澄清,NHibernate使用「保存」,如'SQL INSERT'和'更新',如'SQL UPDATE'。

我知道這些常見的場景時,NHibernate的會從數據庫中堅持前獲取對象隱含(未明確使用s.Update的):(取決於設置)中時

  1. 在session_flush/transaction_commit select-before-update映射設置爲「true」;
  2. 當使用SaveOrUpdate並且實例的標識符有一個表明它存在於數據庫中的值時;
  3. 在s.Delete之前。

與你的例子一樣,當使用父子對象時(但簡單的規則保持不變),這可能並不明顯,因爲它可能不會從代碼中明顯地看到子代將被提取。

2

不,它不會在保存前進行選擇。你確定你的編輯保存用例是正確的嗎?對於web應用常見的流程是:

  • 用戶點擊(GET)上/產品/ 5 /編輯
  • 服務器獲取產品#5到
  • 服務器返回編輯產品#5的HTML表單HTTP會話
  • 用戶提交(POST)形式
  • 服務器從HTTP會話抓住產品#5
  • 服務器從請求填充它
  • 服務器合併填充產品#5返回到第休眠

將執行一個單一的SQL更新,它也會處理版本控制。如果版本號不同步,則會拋出StaleObjectStateException

+0

嗨,thanx的答案。我清楚地看到它發生在保存之前。所以,我只是創建新的對象,然後在道,我做HibernateTemplate.save(對象)。他確實選擇過,我在日誌中看到。我沒有看到更新造成混淆的原因:/ – Julia 2011-04-08 06:15:33

+0

好吧,我提到有關版本問題,我感到困惑。 – cherouvim 2011-04-08 06:17:50

+0

好吧,我已經添加了一個版本專欄,因爲我已經閱讀了hibernate論壇,他們說,爲了避免這種選擇保存之前,應該添加版本列,以便冬眠知道對象是否是暫時的,然後他不做一個選擇。但我仍然無法理解爲什麼他必須這樣做,如果我打電話給保存。 – Julia 2011-04-08 06:23:20

2

So Julia是對的,調用Session.save()與一個實體,其ID分配導致休眠做SELECT然後INSERT。幸運的是有兩種解決方法:

  • 不分配你的ID前面(不是我的選擇)
  • 呼叫Session.persist(),而不是Session.save()

第二種選擇也與無縫工作Envers。

希望這可以節省別人的狩獵時間。

+0

是的,與分配的IDS選擇確實發生(並且它確實有意義),但是我的ID是自動生成的......無論如何,問題已得到解決。但我現在將谷歌session.persist()做了什麼,因爲從未使用它。 thanx – Julia 2012-05-08 13:06:57

+0

非常感謝你!節省了我數小時的狩獵時間,以優化批量節省。 – 2016-07-08 07:47:37

相關問題