2014-01-28 99 views
3

我對ehcache API還不熟悉,所以我可能會漏掉一些明顯的東西,但這是我當前的問題。預加載Ehcache在使用@Cacheable Annotation時被忽略

我目前有一個永久磁盤緩存存儲在我的服務器上。我目前正在實現一種被動的寫後緩存方法,該方法將鍵/值對保存到數據庫表中。如果永久磁盤緩存丟失,我想從數據庫表中恢復緩存。

例子中,我用我的後寫邏輯:

http://scalejava.blogspot.com/2011/10/ehcache-write-behind-example.html

我用下面的方法構建磁盤持久:

import com.googlecode.ehcache.annotations.Cacheable; 
import com.googlecode.ehcache.annotations.KeyGenerator; 
import com.googlecode.ehcache.annotations.PartialCacheKey; 

@Cacheable(cacheName = "readRuleCache", [email protected](name="StringCacheKeyGenerator")) 
public Rule read(@PartialCacheKey Rule rule,String info) {   

    System.out.print("Cache miss: "+ rule.toString()); 

    //code to manipulate Rule object using info 

    try{ 
     String serialziedRule =objectSerializer.convertToString(Rule); 
     readRuleCache.putWithWriter(new Element(rule.toString(),serialziedRule)); 
    } 
    catch(IOException ioe) 
    { 
     System.out.println("error serializing rule object"); 
     ioe.printStackTrace(); 
    } 

    return rule; 
} 

寫方法我覆蓋在我的CacheWriter實現工作正常。事情正在保存到數據庫中。

@Override 
public void write(final Element element) throws CacheException { 

    String insertKeyValuePair ="INSERT INTO RULE_CACHE (ID, VALUE) VALUES " + 
      "('"+element.getObjectKey().toString()+"','" 
       +element.getObjectValue().toString()+"')"; 

    Statement statement; 
     try 
{ 
     statement = connection.createStatement(); 
     statement.executeUpdate(insertKeyValuePair); 
     statement.close(); 

    } catch (SQLException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
} 

查詢和反序列化的字符串返回到對象正常工作了。我已驗證對象的所有值都存在。磁盤永久性緩存也被填充,當我刪除* .data文件,並重新啓動應用程序:

public void preLoadCache() 
{ 
    CacheManager cacheManager = CacheManager.getInstance(); 

    readRuleCache = cacheManager.getCache("readRuleCache"); 

    Query query=em.createNativeQuery("select * from RULE_CACHE"); 

    @SuppressWarnings("unchecked") 
    List<Object[]> resultList = query.getResultList(); 

    for(Object[] row:resultList) 
    { 

     try { 

      System.out.println("Deserializing: "+row[1].toString()); 
      Rule rule = objectSerializer.convertToObject((String)row[1]); 
      rule= RuleValidator.verify(rule); 
      if(rule!=null) 
      { 
       readAirRuleCache.putIfAbsent(new Element(row[0], rule)); 

      } 
     } 
     catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
    } 
} 

問題

一切正常。但是,當我使用應存在於緩存中的鍵傳遞Rule對象時,無論調用「read」方法還是增加* .data文件大小。儘管數據庫的寫入方法不會嘗試再次插入現有密鑰。關於我在做什麼的任何想法都是錯誤的?

回答

1

原來這是罪魁禍首:

[email protected](name="StringCacheKeyGenerator")  

我在此讀出的源材料建議「的toString()」方法我推翻將被用作高速緩存的鍵/值對的密鑰。經過進一步研究後發現這不是事實。雖然使用了「toString()」鍵。它嵌套在類信息中以創建更大的密鑰。

參考:

http://code.google.com/p/ehcache-spring-annotations/wiki/StringCacheKeyGenerator

實施例預期鍵: 「[49931]」

實施例實際鍵: 「[類xyzWeatherDaoImpl,的GetWeather類xyzWeather,[類的java.lang [String],[49931]]「