Search code examples
javacache2k

equal keys trigger cache load more than expected


Maybe I am totally misguided on how cache2k works. I want to cache results from very costly operations, but even with equal keys, the results are always generated again. First I thought, the keys weren't really equal, but even with an equals() returning true, the cache seems to think I want new results.

import org.cache2k.Cache;
import org.cache2k.CacheBuilder;
import org.cache2k.integration.CacheLoader;
import org.junit.Test;

import java.util.Date;
import java.util.concurrent.TimeUnit;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

public class MyCacheTest {

  private static int count = 0;

  Cache<MyCacheTest.MyKey, Integer> cache = (Cache) CacheBuilder.newCache(MyCacheTest.MyKey.class,
      Integer.class)
      .expiryDuration(1, TimeUnit.HOURS)
      .loader(new CacheLoader<MyCacheTest.MyKey, Integer>() {
        @Override
        public Integer load(MyCacheTest.MyKey p) throws Exception {
          return costlyOperation(p);
        }
      })
      .build();

  private Integer costlyOperation(MyKey p) {
    count ++;
    return 1;
  }

  public class MyKey {

    Date date;

    @Override
    public boolean equals(Object o) {
      return true;
    }
  }

  // OK
  @Test
  public void testEquals() {
    assertTrue(new MyKey().equals(new MyKey()));
  }

  // FAIL, somehow calls costlyOperation twice
  @Test
  public void testCostlyOperationCalledOnlyOnce() {
    cache.get(new MyKey());
    cache.get(new MyKey());
    assertEquals(count, 1);
  }
}

This is most likely a misunderstanding on my part, someone please explain why this isn't working as I expect.


Solution

  • You implemented equals but not hashCode and this cache implementation uses hashCode. Adding:

    @Override
    public int hashCode() {
        return 0;
    }
    

    to MyKey gives the expected behavior.

    (tested with version 0.26-BETA)