title: Spring data JPA with Hibernate and Ehcache not working
body: <p>I'm working on an application using Spring Data JPA with Hibernate and I'm trying to enable second level cache using ehcache. I broke up my application into two projects: </p>
  
  <ul>
  <li>CoreDataFacade: where I define data access operations using QueryDSL, Spring Data JPA with Hibernate and ehcache.</li>
  <li>QueryComponent: is a spring boot project that uses CoreDataFacade project to access data.</li>
  </ul>
  
  <p>CoreDataFacade's configuration is as follows:</p>
  
  <p><strong>pom.xml</strong></p>
  
  <pre><code>&lt;dependencies&gt;
      &lt;dependency&gt;
          &lt;groupId&gt;org.springframework.data&lt;/groupId&gt;
          &lt;artifactId&gt;spring-data-jpa&lt;/artifactId&gt;
          &lt;version&gt;1.7.3.RELEASE&lt;/version&gt;
      &lt;/dependency&gt;
  
      &lt;dependency&gt;
          &lt;groupId&gt;org.hibernate&lt;/groupId&gt;
          &lt;artifactId&gt;hibernate-core&lt;/artifactId&gt;
          &lt;version&gt;4.3.6.Final&lt;/version&gt;
      &lt;/dependency&gt;
  
      &lt;dependency&gt;
          &lt;groupId&gt;net.sf.ehcache&lt;/groupId&gt;
          &lt;artifactId&gt;ehcache-core&lt;/artifactId&gt;
          &lt;version&gt;2.4.7&lt;/version&gt;
      &lt;/dependency&gt;
  
      &lt;dependency&gt;
          &lt;groupId&gt;org.hibernate&lt;/groupId&gt;
          &lt;artifactId&gt;hibernate-ehcache&lt;/artifactId&gt;
          &lt;version&gt;4.3.6.Final&lt;/version&gt;  
      &lt;/dependency&gt;
  
      &lt;dependency&gt;
          &lt;groupId&gt;org.hibernate&lt;/groupId&gt;
          &lt;artifactId&gt;hibernate-entitymanager&lt;/artifactId&gt;
          &lt;version&gt;4.3.6.Final&lt;/version&gt;
      &lt;/dependency&gt;
  
      &lt;dependency&gt;
          &lt;groupId&gt;mysql&lt;/groupId&gt;
          &lt;artifactId&gt;mysql-connector-java&lt;/artifactId&gt;
          &lt;version&gt;5.1.33&lt;/version&gt;
      &lt;/dependency&gt;
      &lt;dependency&gt;
          &lt;groupId&gt;c3p0&lt;/groupId&gt;
          &lt;artifactId&gt;c3p0&lt;/artifactId&gt;
          &lt;version&gt;0.9.1.2&lt;/version&gt;
      &lt;/dependency&gt;
      &lt;dependency&gt;
          &lt;groupId&gt;com.mysema.querydsl&lt;/groupId&gt;
          &lt;artifactId&gt;querydsl-apt&lt;/artifactId&gt;
          &lt;version&gt;3.6.0&lt;/version&gt;
      &lt;/dependency&gt;
      &lt;dependency&gt;
          &lt;groupId&gt;com.mysema.querydsl&lt;/groupId&gt;
          &lt;artifactId&gt;querydsl-jpa&lt;/artifactId&gt;
          &lt;version&gt;3.6.0&lt;/version&gt;
      &lt;/dependency&gt;
  </code></pre>
  
  <p><strong>application-context.xml</strong></p>
  
  <pre><code>&lt;jpa:repositories
      base-package="com.coredata.services.impl.sql.mysql.repositories" /&gt;
  
  &lt;bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
      destroy-method="close" p:driverClass="com.mysql.jdbc.Driver"
      p:jdbcUrl="jdbc:mysql://localhost/FOO" p:user="****" p:password="****"
      p:acquireIncrement="5" p:minPoolSize="10" p:maxPoolSize="100"
      p:maxIdleTime="1200" p:unreturnedConnectionTimeout="120" /&gt;
  
  &lt;bean id="jpaVendorAdapter"
      class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"
      p:database="MYSQL" p:showSql="true" p:generateDdl="true" /&gt;
  
  
  &lt;bean id="entityManagerFactory"
      class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
      p:dataSource-ref="dataSource" p:jpaVendorAdapter-ref="jpaVendorAdapter"
      p:packagesToScan="com.coredata.services.impl.sql.mysql.model"&gt;
      &lt;property name="jpaProperties"&gt;
          &lt;props&gt;
              &lt;prop key="hibernate.dialect"&gt;org.hibernate.dialect.MySQL5InnoDBDialect&lt;/prop&gt;
              &lt;prop key="hibernate.cache.use_query_cache"&gt;true&lt;/prop&gt;
              &lt;prop key="hibernate.cache.use_second_level_cache"&gt;true&lt;/prop&gt;
              &lt;prop key="hibernate.cache.provider_class"&gt;org.hibernate.cache.EhCacheProvider&lt;/prop&gt;
              &lt;prop key="hibernate.cache.region.factory_class"&gt;org.hibernate.cache.ehcache.EhCacheRegionFactory
              &lt;/prop&gt;
              &lt;prop key="javax.persistence.sharedCache.mode"&gt;ENABLE_SELECTIVE&lt;/prop&gt;
              &lt;prop key="hibernate.generate_statistics"&gt;true&lt;/prop&gt;
          &lt;/props&gt;
      &lt;/property&gt;
  &lt;/bean&gt;
  
  &lt;bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager" /&gt;
  </code></pre>
  
  <p><strong>Entity Cache annotations</strong></p>
  
  <pre><code>@Entity
  @Cacheable
  @Cache(usage = CacheConcurrencyStrategy.READ_ONLY, region="cache_states")
  @Table(name="states")
  public class State implements Serializable {
      private static final long serialVersionUID = 1L;
  
      @Id
      @GeneratedValue(strategy=GenerationType.IDENTITY)
      @Column(name="id_state")
      private int idState;
      ...
  </code></pre>
  
  <p><strong>ehcache.xml</strong></p>
  
  <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  &lt;ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"&gt;
  
      &lt;defaultCache maxElementsInMemory="10000" eternal="false"
          timeToIdleSeconds="120" timeToLiveSeconds="120"
          overflowToDisk="false" diskPersistent="false" /&gt;
  
      &lt;cache name="cache_states" maxElementsInMemory="300" eternal="false"
          timeToIdleSeconds="5000" timeToLiveSeconds="5000" overflowToDisk="false"&gt;
      &lt;/cache&gt;
  &lt;/ehcache&gt;
  </code></pre>
  
  <p>QueryComponent's configuration imports above configuration and exclude JPA:</p>
  
  <pre><code>@Configuration
  @PropertySource("classpath:/component.properties")
  @ImportResource({ "classpath:/application-context.xml"})
  @EnableAutoConfiguration(exclude = { JpaRepositoriesAutoConfiguration.class })
  public class Application {
  
      public void run(String... args) {   }
  
      public static void main(String[] args) {
          SpringApplication.run(Application.class, args);
      }
  }
  </code></pre>
  
  <p>When ComponentQuery starts everything is OK. When I execute a query to find all states in database, hibernate statistics are as follows:</p>
  
  <pre><code>Hibernate: select count(state0_.id_state) as col_0_0_ from states state0_
  Hibernate: select state0_.id_state as id_stat1_5_, state0_.name_state as  name_e2_5_ from states state0_ limit ?
  [2015-08-31 18:52:21.402] boot - 1946  INFO [SimpleAsyncTaskExecutor-1]    --- StatisticalLoggingSessionEventListener:    Session Metrics {
      32992 nanoseconds spent acquiring 1 JDBC connections;
      0 nanoseconds spent releasing 0 JDBC connections;
      238285 nanoseconds spent preparing 2 JDBC statements;
      935976 nanoseconds spent executing 2 JDBC statements;
      0 nanoseconds spent executing 0 JDBC batches;
      269717 nanoseconds spent performing 4 L2C puts;
      0 nanoseconds spent performing 0 L2C hits;
      0 nanoseconds spent performing 0 L2C misses;
      0 nanoseconds spent executing 0 flushes (flushing a total of 0 entities and 0 collections);
      68790 nanoseconds spent executing 2 partial-flushes (flushing a total of 0 entities and 0 collections)
    }
  </code></pre>
  
  <p>When I repeat the same query I got this statistics:</p>
  
  <pre><code>Hibernate: select count(state0_.id_state) as col_0_0_ from states state0_
  Hibernate: select state0_.id_state as id_stat1_5_, state0_.name_state as  name_e2_5_ from states state0_ limit ?
  [2015-08-31 19:26:48.479] boot - 1946  INFO [SimpleAsyncTaskExecutor-1]    --- StatisticalLoggingSessionEventListener:     Session Metrics {
      314930 nanoseconds spent acquiring 1 JDBC connections;
      0 nanoseconds spent releasing 0 JDBC connections;
      356832 nanoseconds spent preparing 2 JDBC statements;
      681615 nanoseconds spent executing 2 JDBC statements;
      0 nanoseconds spent executing 0 JDBC batches;
      209324 nanoseconds spent performing 4 L2C puts;
      0 nanoseconds spent performing 0 L2C hits;
      0 nanoseconds spent performing 0 L2C misses;
      0 nanoseconds spent executing 0 flushes (flushing a total of 0 entities and 0 collections);
      12368 nanoseconds spent executing 2 partial-flushes (flushing a total of 0 entities and 0 collections)
  }
  </code></pre>
  
  <p>It seems that every query is putting results (4 states in database) in cache:</p>
  
  <pre><code>    269717 nanoseconds spent performing 4 L2C puts;
      209324 nanoseconds spent performing 4 L2C puts;
  </code></pre>
  
  <p>I expect second query to retrive data from cache but it statistics hits and misses are zero:</p>
  
  <pre><code>    0 nanoseconds spent performing 0 L2C hits;
      0 nanoseconds spent performing 0 L2C misses;
  </code></pre>
  
  <p>My question is: why L2C hits and L2C misses are zero when I execute second query?</p>
  
  <p><strong>UPDATE</strong></p>
  
  <p>This is how I'm running my query</p>
  
  <p><strong>Reposiory</strong></p>
  
  <p>I'm working with QueryDSL with spring data jpa. I followed this <a href="http://www.javabeat.net/spring-data-jpa-querydsl-integration/">tutorial</a> to integrate my JpaRepository using <a href="http://docs.spring.io/spring-data/commons/docs/current/api/org/springframework/data/querydsl/QueryDslPredicateExecutor.html">QueryDslPredicateExecutor</a> </p>
  
  <pre><code>public interface StateRepository extends JpaRepository&lt;State, Integer&gt;, QueryDslPredicateExecutor&lt;State&gt; {
   }
  </code></pre>
  
  <p><strong>Service</strong></p>
  
  <p>In my service I execute my query using queryDLS predicates and PathBuilder as shown in this great <a href="http://www.baeldung.com/rest-api-search-language-spring-data-querydsl">article</a> so that, I can find States or any other entity by any field. E.g "StateName=Texas", "StatePopulation=26448193".</p>
  
  <pre><code>@Autowired
  StateRepository repo;
  
  public List&lt;State&gt; getStatesByFields(String options, Integer page, Integer pageSize,String order) {
      PredicateBuilder predicateBuilder = new PredicateBuilder().onEntity("State")
      Pattern pattern = Pattern.compile(OPERATION_PATTERN);
      Matcher matcher = pattern.matcher(options + ",");
      while (matcher.find()) {
          predicateBuilder.with(matcher.group(1), matcher.group(2), matcher.group(3));
      }
      PageRequest pag = new PageRequest(page, page_size)
      BooleanExpression predicate = predicateBuilder.build();
      //findAll is provided by QueryDslPredicateExecutor interface
      Page&lt;State&gt; result = repo.findAll(predicate, pag);
  }
  </code></pre>
  
  <p>Queries runs like charm, but data seems not be cached.</p>