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?