I have implemented a kind of caching bean to cache data objects as an EJB Singleton. I wonder if this is the correct way in EJB:
@Singleton
public class MyCache {
int DEFAULT_CACHE_SIZE = 30;
int DEFAULT_EXPIRES_TIME = 60000;
long expiresTime = 0;
long lastReset = 0;
Cache cache = null;
....
@PostConstruct
void init() {
resetCache();
}
public void resetCache() {
cache = new Cache(DEFAULT_CACHE_SIZE);
lastReset = System.currentTimeMillis();
}
public void put(String key, Object value) {
cache.put(key, value);
}
public Object get(String key) {
// test if cache is expired
if (expiresTime > 0) {
Long now = System.currentTimeMillis();
if ((now - lastReset) > expiresTime) {
logger.finest("...... Cache expired!");
resetCache();
}
}
return cache.get(key);
}
class Cache extends LinkedHashMap<String, Object> implements Serializable {
private static final long serialVersionUID = 1L;
private final int capacity;
public Cache(int capacity) {
super(capacity + 1, 1.1f, true);
this.capacity = capacity;
}
protected boolean removeEldestEntry(Entry<String, Object> eldest) {
return size() > capacity;
}
}
}
My question is: is this the right way to implement an application wide caching mechanism?
I have the impression that the contents of the cache are unexpectedly changing. Could this happen? For example, if the EJB is passivated? I am running in a Payara41 Server.
Or must I use:
cache = Collections.synchronizedMap(new Cache(DEFAULT_CACHE_SIZE));
instead of:
cache = new Cache(DEFAULT_CACHE_SIZE);