2015-03-31 125 views
0

所以,我的問題是我不確定我的查詢是否被緩存。我現在擁有的hibernate.xml使用ehcache作爲二級緩存。使用Criteria查詢進行Hibernate緩存

現在這是我的測試代碼:

Session session = HibernateUtil.getCurrentSession(); 
    Criteria criteria = session.createCriteria(Users.class); 
    criteria.add(Restrictions.eq("id", "777008")); 

    Users user = (Users) criteria.uniqueResult(); 

    HibernateUtil.closeCurrentSession(); 

    Session anotherSession = HibernateUtil.getCurrentSession(); 
    Criteria anotherCriteria = anotherSession.createCriteria(Users.class); 
    anotherCriteria.add(Restrictions.eq("id", "777008")); 

    Users anotherUser = (Users) anotherCriteria.uniqueResult(); 

HibernateUtil.getCurrentSession()方法在ThreadLocal變量檢索當前的會話,如果它是可用的。如果會話爲空,則會創建一個會話。

HibernateUtil.closeCurrentSession()ThreadLocal變量中獲取會話,如果它不爲空則關閉它。當我運行上面的代碼(這是一個JUnit測試)時,我只能看到一個從數據庫中選擇的Hibernate日誌。因爲我沒有用Criteria.setCaching(true)來強制緩存任何東西,所以我期待有兩個。

我相信一級緩存只存在於會話範圍內,二級緩存基本上是應用程序緩存。在上面的兩個criteria.uniqueResult()調用的中間,我關閉了會話。

我的問題是,爲什麼我只看到一個Hibernate SELECT語句日誌?我不應該看到兩個嗎?另外,當我去我的hibernate.xml並禁用第二級緩存時,仍然會出現相同的輸出,這真是令我困惑不已。

我看到的SELECT語句日誌的例子:`Hibernate:select this_.id as id8_0_,this_.nameas name8_0_,from users this_ where this_.id =?

編輯:我這次嘗試了不同的方法。請參閱下面的下面的代碼片段:

@Test 
public void testCaching(){ 

    for (int i = 0; i < 10; i++){ 


     try { 
      Thread.sleep(3000); 

      logger.info("Retrieving user."); 
      Session session = HibernateUtil.getCurrentSession(); 
      Criteria criteria = session.createCriteria(Users.class); 
      criteria.add(Restrictions.eq("id", "777008")); 
      criteria.setCacheable(true); 

      Users user = (Users) criteria.uniqueResult(); 

     } 
     catch (Exception ex){ 
      System.out.println("Got it"); 
     } 
     finally{ 
      HibernateUtil.closeCurrentSession(); 

     } 
    } 
} 

所以,現在,每一個測試調用Criteria.uniqueResult()時,它會顯示一個Hibernate日誌。那麼現在,我關心的是我甚至緩存了什麼?使用此測試啓用第二級緩存(ehcache)。編輯2:好吧,現在,我有點想法爲什麼它不緩存。原來,我必須把<cache usage="read-write"/>放在我對象的XML的<class>之內。但是,我不能這樣做,因爲其他應用程序也在使用XML。無論如何只能在應用程序上啓用緩存嗎?

回答

0

您會看到一個查詢,因爲id = 777008的User對象已經在Hibernate上下文中。嘗試使用名稱字段而不是@Id字段查詢,您應該看到兩個查詢。

還可以在您的配置中全局地打開查詢緩存,而無需爲特定查詢設置該緩存。

+0

因此,它已經在Hibernate環境中,這是否意味着它被緩存?爲什麼我應該使用名稱字段?我只能使用ID字段進行查詢。由於我不被允許,我無法真正全局配置它來緩存。 hibernate.xml也被其他應用程序使用。 – mpmp 2015-03-31 18:29:06

+0

對不起,我的意思是,如果您使用的查詢不是基於id的查詢,而是使用其他屬性,則會看到兩個查詢。是的,最近的對象被緩存在hibernate上下文中,並且基於id的搜索首先進入該上下文。例如,如果您有一些@OneToMany用戶集合(除非您有批量提取),那麼您將不會看到所有用戶的sql語句,但僅針對那些尚未處於上下文中的用戶。 – Zielu 2015-03-31 18:34:15

+0

嗯..你在Hibernate上下文中失去了我。我相信只有兩種類型的緩存:一級緩存(會話作用域)和二級緩存(應用程序作用域)。你指的是哪個範圍?它不能在會話範圍內,因爲我在第一次查詢後關閉會話。它可能不在應用程序範圍內,因爲當我在Hibernate中轉換第二級緩存時,我仍然得到相同的結果:/ – mpmp 2015-03-31 19:42:30