title: SpringBoot + JPA enable second level caching for entity not working
body: <p>I am using Springboot 2.1 and spring data-jpa for persistence using <strong>@RepositoryRestResource</strong>. I have enabled caching for my API calls and that works well with <strong>@Cacheable</strong>, But now I want to enable <strong>second-level cache</strong> for all my JPA entities and have below configurations but still any query on these entities are firing hibernate queries and not using cache.
  Please let me know what I am missing for this Entity caching.</p>
  
  <p>Gradle Dependency:</p>
  
  <pre><code>dependencies {
  implementation 'org.springframework.boot:spring-boot-starter-web'
  implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
  implementation 'org.springframework.boot:spring-boot-starter-data-redis'
  implementation 'org.springframework.boot:spring-boot-starter-data-rest'
  implementation 'org.springframework.boot:spring-boot-starter-hateoas'
  implementation 'org.springframework.boot:spring-boot-starter-jersey'
  
  implementation 'org.springframework.boot:spring-boot-starter-cache'
  implementation  'org.ehcache:ehcache:3.7.1'
  implementation 'javax.cache:cache-api'
  compile group: 'org.hibernate', name: 'hibernate-jcache', version: '5.3.10.Final'
  
  runtimeOnly 'mysql:mysql-connector-java'
  </code></pre>
  
  <p>}</p>
  
  <p>application.properties</p>
  
  <pre><code>    spring.datasource.url=jdbc:mysql://localhost:3306/mar_db
  spring.datasource.username=root
  spring.datasource.password=
  
  spring.jpa.database-platform=org.hibernate.dialect.MySQL57Dialect
  spring.jpa.show-sql=true
  spring.jpa.properties.hibernate.format_sql=true 
  spring.jpa.hibernate.ddl-auto=update
  
  spring.jpa.properties.hibernate.cache.use_query_cache=true
  spring.jpa.properties.hibernate.cache.use_second_level_cache=true
  spring.jpa.properties.hibernate.cache.region.factory_class=org.hibernate.cache.jcache.JCacheRegionFactory
  spring.jpa.properties.javax.persistence.sharedCache.mode=ENABLE_SELECTIVE
  
  spring.cache.jcache.config=classpath:ehcache.xml
  </code></pre>
  
  <p>ehcache.xml</p>
  
  <pre><code>&lt;config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.ehcache.org/v3"
          xmlns:jsr107="http://www.ehcache.org/v3/jsr107"&gt;
  
      &lt;service&gt;
          &lt;jsr107:defaults enable-statistics="true" /&gt;
      &lt;/service&gt;
      &lt;cache alias="readOnlyEntityData"&gt;
          &lt;key-type&gt;java.lang.Object&lt;/key-type&gt;
          &lt;expiry&gt;
              &lt;ttl unit="minutes"&gt;360&lt;/ttl&gt;
          &lt;/expiry&gt;
          &lt;listeners&gt;
              &lt;listener&gt;
                  &lt;class&gt;com.tfsc.ilabs.selfservice.common.utils.CacheLogger&lt;/class&gt;
                  &lt;event-firing-mode&gt;ASYNCHRONOUS&lt;/event-firing-mode&gt;
                  &lt;event-ordering-mode&gt;UNORDERED&lt;/event-ordering-mode&gt;
                  &lt;events-to-fire-on&gt;CREATED&lt;/events-to-fire-on&gt;
                  &lt;events-to-fire-on&gt;UPDATED&lt;/events-to-fire-on&gt;
                  &lt;events-to-fire-on&gt;EXPIRED&lt;/events-to-fire-on&gt;
                  &lt;events-to-fire-on&gt;REMOVED&lt;/events-to-fire-on&gt;
                  &lt;events-to-fire-on&gt;EVICTED&lt;/events-to-fire-on&gt;
              &lt;/listener&gt;
          &lt;/listeners&gt;
          &lt;resources&gt;
              &lt;heap unit="entries"&gt;1000&lt;/heap&gt;
              &lt;offheap unit="MB"&gt;256&lt;/offheap&gt;
          &lt;/resources&gt;
      &lt;/cache&gt;
  &lt;/config&gt;
  </code></pre>
  
  <p>Config.java</p>
  
  <pre><code>import org.hibernate.annotations.CacheConcurrencyStrategy;
  
  import javax.persistence.Cacheable;
  import javax.persistence.Column;
  import javax.persistence.Entity;
  import javax.persistence.Id;
  import javax.validation.constraints.NotNull;
  import java.util.Objects;
  
  @Entity
  @Cacheable
  @org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE, region = "readOnlyEntityData")
  public class Config {
  
      @Id
      @NotNull
      @Column(unique = true)
      private String code;
      @NotNull
      private String value;
      @NotNull
      @Column(columnDefinition = "boolean default true")
      private boolean status;
      @NotNull
      private String type;
  
     ......
  }
  </code></pre>
  
  <p>Service class:</p>
  
  <pre><code>import org.springframework.beans.factory.annotation.Autowired;
  import org.springframework.cache.annotation.Cacheable;
  import org.springframework.stereotype.Service;
  
  import java.util.List;
  import java.util.Optional;
  import java.util.stream.Collectors;
  
  @Service
  public class DBConfigServiceImpl implements DBConfigService {
  
      @Autowired
      private DBConfigRepository dbConfigRepository;
  
      @Override
      public List&lt;ConfigDTO&gt; findAll() {
          return dbConfigRepository.findAll().stream().map(Config::toDTO).collect(Collectors.toList());
      }
  
      @Cacheable(value = "readOnlyEntityData", keyGenerator = "cacheKeyGenerator")
      @Override
      public ConfigDTO findByCode(String code) {
          Optional&lt;Config&gt; config =  dbConfigRepository.findById(code);
          if(config.isPresent()){
              return config.get().toDTO();
          }else {
              throw new NoSuchResourceException(new ErrorObject("Config not found {0}", code));
          }
      }
  }
  </code></pre>
  
  <p>JpaRepository:</p>
  
  <pre><code>import org.springframework.data.jpa.repository.JpaRepository;
  import org.springframework.data.rest.core.annotation.RepositoryRestResource;
  
  @RepositoryRestResource
  public interface DBConfigRepository extends JpaRepository&lt;Config, String&gt; {
  }
  </code></pre>
  
  <p>Only Methods marked with <strong>@Cacheable</strong> responses are cached and works well, But when It comes to Entity level caching of data, always db query is fired to pull the data.  Please let me know what I am missing here.</p>
  
  <p>Edit: Found that only JPA's <strong>findById()</strong> returns from the cache as hibernate cache is stored in hydrated form as key value pair, where id is the key. Whereas <strong>findAll()</strong> and <strong>findByType()</strong> etc methods always fires DB queries to get data. How to make them store and return from cache.? </p>