2013-03-01 32 views
0

我們使用以下屬性啓用有關休眠二級緩存:Hibernate的二級緩存延遲集合大小

hibernateProperties.setProperty("hibernate.cache.region.factory_class", "org.hibernate.cache.ehcache.EhCacheRegionFactory"); 
hibernateProperties.setProperty("hibernate.cache.use_query_cache", Boolean.TRUE.toString()); 
hibernateProperties.setProperty("hibernate.cache.use_second_level_cache", Boolean.TRUE.toString()); 
hibernateProperties.setProperty("hibernate.cache.use_structured_entries", Boolean.TRUE.toString());  
hibernateProperties.setProperty("hibernate.cache.generate_statistics", Boolean.TRUE.toString()); 

而且使用緩存標籤標記我們的實體:

@Entity 
@Indexed 
@Table(name = "item") 
@Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL) 
public class Item implements Serializable { 

這個實體有一個懶惰的收集與懶惰收集選項額外:

@Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL) 
@ManyToMany(fetch = FetchType.LAZY, targetEntity = User.class, mappedBy = "likes") 
@LazyCollection(LazyCollectionOption.EXTRA) 
private List<User> users; 

這似乎運作良好,我沒有看到任何數據庫查詢中的數據已經被緩存之後,但是我們確實看到有一個日誌調用來

select count(user_id) from user_items where item_id =? 

有沒有什麼辦法讓冬眠緩存的大小懶惰的收集,所以當我們做users.size()時它不需要擊中數據庫?


我已更改爲CacheConcurrencyStrategy.READ_WRITE並查看相同的行爲。

在第一個請求中,我看到查詢選擇實體和查詢以查找集合的大小。我看到日誌消息說實體正在被緩存。

在隨後的請求中,沒有調用來加載實體,但仍然有調用來查找集合的大小。

回答

0

當數據被緩存時,您永遠不會看到數據庫查詢。並且您在說有選擇查詢的連續日誌。 Ehcache不提供事務性緩存。 你在說它是在工作。 兄弟它不工作,你只是有數據庫調用和日誌相同。 檢查Ehcache文檔,因爲它不支持TRANSACTIONAL緩存

+0

「Ehcache文檔,因爲它不支持TRANSACTIONAL緩存」 - 這是什麼意思,你認爲事務緩存是什麼? – NimChimpsky 2013-03-01 10:43:29

+0

我已更改爲CacheConcurrencyStrategy.READ_WRITE並查看相同的行爲。在第一個請求中,我看到查詢以選擇實體和查詢來查找集合的大小。我看到日誌消息說實體正在被緩存。在隨後的請求中,沒有調用來加載實體,但仍然有調用來查找集合的大小。 – Chris 2013-03-01 11:12:41

0

用戶列表是一個延遲加載的集合。 在Lazy loaded collection中,您不會有任何數據。 無論何時你想要訪問Lazy加載的集合,或者你想確定延遲加載的集合的大小,它都必須有關於其中的數據的信息,比如有多少個元素。 爲此,它將從數據庫獲取該數據,並因此每次都會生成數據庫查詢。 我檢查了這兩個列表作爲最高層和其他一些對象。 這表明當List不是頂級對象時,它將被懶惰地初始化。 因此,無論何時想要獲取有關集合的信息或從集合中獲取信息,都將生成數據庫查詢。

相關問題