EhCache에서는 똑같은 Key를 가지고 요청하여도 항상 CacheMiss가 발생합니다. EhCache는 아래와 같이 캐시 저장소에 접근할 때 해시 테이블 접근을 위해 Object의 hashCode 메소드와 해시 충돌 처리를 위해 equals 메소드를 사용합니다.
package net.sf.ehcache.store.chm;
... (생략) ...
class SelectableConcurrentHashMap {
... (생략) ...
public Element get(Object key) { // StringKeyGenerator, SimpleStringKeyGenerator를 사용할 경우 key는 ArcusStringKey 클래스
int hash = hash(key.hashCode());
return segmentFor(hash).get(key, hash);
}
Element get(final Object key, final int hash) { // StringKeyGenerator, SimpleStringKeyGenerator를 사용할 경우 key는 ArcusStringKey 클래스
readLock().lock();
try {
if (count != 0) { // read-volatile
HashEntry e = getFirst(hash);
while (e != null) {
if (e.hash == hash && key.equals(e.key) && !e.value.equals(DUMMY_PINNED_ELEMENT)) {
e.accessed = true;
return e.value;
}
e = e.next;
}
}
return null;
} finally {
readLock().unlock();
}
}
... (생략) ...
}
StringKeyGenerator, SimpleStringKeyGenerator는 Key 생성시 ArcusStringKey라는 클래스의 Object를 리턴하는데, 이 클래스의 hashCode, equals 메소드가 구현되어있지 않아, jvm에서 생성하는 hashCode를 사용하게 됩니다. 따라서 같은 Key를 요청했음에도 불구하고 생성되는 ArcusStringKey 인스턴스의 hashCode는 매번 다르기 때문에 CacheMiss가 항상 발생하게 됩니다.
package java.lang;
class Object {
... (생략) ...
@HotSpotIntrinsicCandidate
public native int hashCode();
public boolean equals(Object obj) {
return (this == obj);
}
... (생략) ...
}
따라서 ArcusStringKey의 hashCode와 equals를 override하여, StringKeyGenerator, SimpleStringKeyGenerator 클래스가 다른 캐시 구현체에서도 사용될 수 있도록 수정하였습니다.
arcus-spring에서 제공하는 키 생성 클래스인 StringKeyGenerator, SimpleStringKeyGenerator를 다른 Cache 구현체에서 사용하면, 반복적인 Cache Miss가 발생하여, 이를 수정하였습니다.
만약 아래와 같이 응용 코드에서 ArcusCacheManager, EhCacheManager를 둘 다 사용하고, arcus-spring에서 제공되는 StringKeyGenerator를 사용할 경우
EhCache에서는 똑같은 Key를 가지고 요청하여도 항상 CacheMiss가 발생합니다. EhCache는 아래와 같이 캐시 저장소에 접근할 때 해시 테이블 접근을 위해 Object의
hashCode
메소드와 해시 충돌 처리를 위해equals
메소드를 사용합니다.StringKeyGenerator, SimpleStringKeyGenerator는 Key 생성시 ArcusStringKey라는 클래스의 Object를 리턴하는데, 이 클래스의
hashCode
,equals
메소드가 구현되어있지 않아, jvm에서 생성하는hashCode
를 사용하게 됩니다. 따라서 같은 Key를 요청했음에도 불구하고 생성되는 ArcusStringKey 인스턴스의hashCode
는 매번 다르기 때문에 CacheMiss가 항상 발생하게 됩니다.따라서 ArcusStringKey의 hashCode와 equals를 override하여, StringKeyGenerator, SimpleStringKeyGenerator 클래스가 다른 캐시 구현체에서도 사용될 수 있도록 수정하였습니다.