简体   繁体   中英

Preloaded Ehcache Ignored when using @Cacheable Annotation

I'm still new to the ehcache API so I may be missing something obvious but here's my current issue.

I currently have a persistent-disk cache that's being stored on my server. I'm currently implementing a passive write-behind cache method that saves key/value pairs to a database table. In the event the persistent-disk cache is lost, I'd like to restore the cache from the database table.

Example I'm using for my write-behind logic:

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

I'm building a disk persistent using the following method:

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

@Cacheable(cacheName = "readRuleCache", keyGenerator=@KeyGenerator(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;
}

The write method I'm overriding in my CacheWriter implementation works fine. Things are getting saved to the database.

 @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();
    }
}

Querying and De-serializing the string back in to an object works fine too. I've validated that all the values of the object are present. The disk persistent cache is also being populated when I delete the *.data file and restart the application:

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();
        }
     }
}

Question

Everything looks OK. However when I pass Rule objects with keys that should exist in the cache the "read" method is called regardless and the *.data file size is increased. Though the write method for the database doesn't attempt to insert existing keys again. Any ideas on what I'm doing wrong?

It turns out this was the culprit:

keyGenerator=@KeyGenerator(name="StringCacheKeyGenerator")       

The source material I read on this suggested that the "toString()" method I overrode would be used as the key for the cache key/value pair. After further research it turns out that this is not true. Though the "toString()" key is used. It is nested within class information to create a much larger key.

Reference:

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

Example Expected key: "[49931]"

Example Actual Key: "[class xyzWeatherDaoImpl, getWeather class xyzWeather, [class java.lang.String], [49931]]"

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM