Reference service for a cache
Design Fix

The correct solution to this is to make your cache responsible for retrieving the entity on cache-miss.

Consider for a moment the goals of a cache:


Keep expensive to calculate / retrieve information in a manner suitable to quick access
Abstract away cache handling (invalidation, cache-misses, ...) from consumers
Give certain guarantees for the consistency of cached information


As it stands the way this code is setting up and using the cache utterly fails on the second point. Luckily javax.caching.Cache does support loading entries into the cache on misses using a CacheLoader.

For this to happen you need to create a CacheLoader that is aware of the EntityManager used to access the entities:

[..] config = new MutableConfiguration&lt;String, T&gt;()
  .setTypes(String.class, type)
  .setReadThrough(true) // enables silent loading
  .setCacheLoaderFactory(new FactoryBuilder.SingletonFactory(
    new CacheLoader&lt;String, T&gt;() {
      @Override
      public T load(String key) {
          return entityManager.find(type, key);
      }
      @Override
      public Map&lt;String, T&gt; loadAll(Iterable&lt;? extends String&gt; keys) {
          return Stream.of(keys)
            .collect(Collectors.toMap(Function.identity(), this::load));
      }
   });


You should notice at this point that you're locking yourself into caching on a single primary key (namely String). This is something that might bite you in the backside down the road, but if you only use Strings as primary keys for entities that should be alright.

n.b. that I haven't even checked whether this code compiles.