sebastiandaschner blog

JCache with MapDB as persistence provider

monday, april 06, 2015

When using JCache the caches are not persisted with standard features. Therefore custom CacheWriters and CacheLoaders can be used. These two can be combined with any kind of storage, for example a persistent MapDB instance.

MapDB is an easy to use HashMap-like storage with optional persistence. The CacheWriter and CacheLoader are configured as follows:

final DB mapDB = DBMaker.newFileDB(dbLocation).asyncWriteEnable().make();

final Configuration<String, String> config = new MutableConfiguration<String, String>()
    .setTypes(String.class, String.class)
    .setCacheWriterFactory(() -> new CacheWriter<String, String>() {

        private BTreeMap<Object, Object> map = mapDB.getTreeMap("default-map");

        public void write(final Cache.Entry<? extends String, ? extends String> entry) throws CacheWriterException {
            map.put(entry.getKey(), entry.getValue());

        // writeAll, delete, deleteAll ...
    .setCacheLoaderFactory(() -> new CacheLoader<String, String>() {

        private BTreeMap<Object, Object> map = mapDB.getTreeMap("default-map");

        public String load(final String key) throws CacheLoaderException {
            return (String) map.get(key);

        // loadAll ...

final Cache<String, String> cache = Caching.getCachingProvider().getCacheManager()
    .createCache("name", config);

As the CacheWriter is synchronous by default the write execution should be performed asynchronously to make writes faster (if writing fast is an important requirement). This can be achieved by asyncWriteEnable for MapDB or by submitting a task to the ManagedExecutorService for custom solutions.

See JCache persistence example for a fully JavaEE-integrated example.


Found the post useful? Subscribe to my newsletter for more free content, tips and tricks on IT & Java: