title: How to use JPA2's @Cacheable instead of Hibernate's @Cache
body: <p>Typically , I use Hibernate's <strong>@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)</strong> to cache an @Entity class , and it works well. </p>
  
  <p>In JPA2 , there's another @Cacheable annotation that seems to be the same functionality with Hibernate's @Cache. To make my entity class independent of hibernate's package , I want to give it a try. But I cannot make it work. Each time a simple id query still hits the DB.</p>
  
  <p>Can anybody tell me where goes wrong ? Thanks.</p>
  
  <p>Entity class :</p>
  
  <pre><code>@Entity
  //@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
  @Cacheable(true) 
  public class User implements Serializable
  {
   // properties
  }
  </code></pre>
  
  <p>Test class :</p>
  
  <pre><code>@RunWith(SpringJUnit4ClassRunner.class)
  @ContextConfiguration(locations={"classpath:app.xml"})
  @TransactionConfiguration(transactionManager="transactionManager")
  public class UserCacheTest
  {
    @Inject protected UserDao userDao;
  
    @Transactional
    @Test
    public void testGet1()
    {
      assertNotNull(userDao.get(2L));
    }
  
    @Transactional
    @Test
    public void testGet2()
    {
      assertNotNull(userDao.get(2L));
    }
  
    @Transactional
    @Test
    public void testGet3()
    {
      assertNotNull(userDao.get(2L));
    }
  }
  </code></pre>
  
  <p>The test result shows each "get" hits DB layer (with hibernate.show_sql=true).</p>
  
  <p>Persistence.xml :</p>
  
  <pre><code>&lt;property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/&gt;
  &lt;property name="hibernate.show_sql" value="true"/&gt;
  &lt;property name="hibernate.format_sql" value="true" /&gt;
  &lt;property name="hibernate.use_outer_join" value="true"/&gt;
  
  &lt;property name="hibernate.cache.provider_class" value="org.hibernate.cache.SingletonEhCacheProvider"/&gt;
  &lt;property name="hibernate.cache.use_second_level_cache" value="true"/&gt;
  &lt;property name="hibernate.cache.use_query_cache" value="true"/&gt;
  </code></pre>
  
  <p>JPA code :</p>
  
  <pre><code>@Override
  public T get(Serializable id)
  {
    return em.find(clazz, id);
  }
  </code></pre>