2009-08-25 115 views
13

我有一個Hibernate域對象,它被應用程序的不同部分加載。有時延遲加載每個關聯和其他的更有利於在一個連接中加載整個事物。作爲一個希望愉快的妥協,我發現:休眠:batch_size?二級緩存?

使用批量獲取,Hibernate可以加載幾個未初始化的代理,如果一個代理被訪問。批量抓取是對懶惰選擇抓取策略的優化。

hibernate.default_batch_fetch_size

使用批量抓取,Hibernate可以加載 如果一個訪問代理其他未代理。批量抓取是對懶惰選擇抓取策略的優化。

我也參見:

hibernate.jdbc.fetch_size

非零值,指定JDBC抓取大小(調用Statement.setFetchSize())。

那麼Hibernate是否足夠聰明,可以在進行批量抓取時查看二級緩存?也就是說,是否有初始調用訪問關聯,然後接下來的X個調用是否會觸發緩存?通過這種方式,我可以獲得我想要的延遲加載,但也經常爲更大容量的事務啓動緩存。

如果集合的全部內容已經包含在緩存中,它是否仍然執行對集合訪問的提取查詢?

謝謝。

+0

現在,我也想知道答案。 – Zoidberg 2009-08-25 16:58:11

+1

標記我的問題:-) – davidemm 2009-08-25 17:20:56

回答

6

我今天做了很多研究,並能夠對自己的問題做出迴應。我正在瀏覽Hibernate代碼,流程如下所示:

集合是否已初始化?

  • 不是嗎?執行批量提取(通過批量提取獲取的項目放在緩存中)
  • 是嗎?在緩存中查找特定項目,如果它不在那裏進行批量提取。

因此,如果您正在尋找的集合中的項目在緩存中找到,那麼批量獲取不會發生。如果在二級緩存中未找到該項目,則會發生批量提取,但是會批量提取批量項目,而不管批量項目是否在緩存中。


-----例1 -----

優點:

(三一級集合中的項目 - 3批量大小) 第一次去:

  • collection.getItem(0) - No cache |批量取3項
  • 集合。的getItem(1) - 通過加載批量取
  • collection.getItem(2) - 通過加載批量取

現在,別的地方,後來時間:

  • 集合。的getItem(0) - 高速緩存命中
  • collection.getItem(1) - 高速緩存命中
  • collection.getItem(2) - 高速緩存命中

-----實施例2 -----

缺點:

(在收集三個項目 - 3批量大小)

在這種情況下,在索引0處的項目是從緩存中刪除,因爲可能緩存已滿並且該項目已被刪除,或項目已過時或空閒。

  • collection.getItem(0) - 不在緩存所以做批3(SELECT *凡在(,ID)???)
  • collection.getItem(1) - 在緩存中已經(被替換反正通過批量提取)
  • collection.getItem(2) - 在緩存中已經(被替換反正批量提取)

所以在這裏下車的交易是,你有較少的SQL調用由於批處理,但你會錯過更多的緩存。有一張票可以在第二級緩存中查看批處理,然後發送到數據庫。

http://opensource.atlassian.com/projects/hibernate/browse/HHH-1775

投上一票!