Search code examples
javaguava

Google Guava cache calling load method every time even if the key exists


I am trying to use Guava Cache [version 29.0-jre] as with Guice as follows:

Guava Cache impl

My observation is, Guava cache is calling the load method every time even when the key exists in the cache. Why is this happening?

Debug console

In the above debug console we can observe that the key [uuid] and value [json object] are already present in the cache. However, on the next get request the control still goes inside load method.

Another observation is, I tried multiple attempts and can see entries with the same key getting loaded multiple times in the cache.

entries with the same key loaded to cache


Solution

  • we can observe that the key [uuid]

    There's your error. That's not the key. You said it yourself: .weakKeys() is in your CacheBuilder setup. The key isn't the UUID, it's the identity of the object representing it.

    From the CacheBuilder docs:

    Note: by default, the returned cache uses equality comparisons (the equals method) to determine equality for keys or values. However, if weakKeys() was specified, the cache uses identity (==) comparisons instead for keys. Likewise, if weakValues() or softValues() was specified, the cache uses identity comparisons for values.

    Thus, the key is not the UUID you're seeing. It's the literal object identity of that UUID object. Let me try to explain with an example. Imagine your cache had String keys.

    // Without .weakKey:
    
    String a = new String("Hello");
    String b = new String("Hello");
    
    are the same key.
    
    // With .weakKey THEY ARE NOT, because..
    
    a == b; // this is false. Thus, .weakKeys() cache says not equal.
    a.equals(b); // this is true. Thus, strong keys cache says equal.
    

    You seem to want both the 'use .equals for identity' aspect, as well as '... but don't impede garbage collection' aspect. I'm not aware of an easy way to get that.