近来用jpa来做持久化开发(具体实现是hibernate),想配置一下二级缓存,网上查了不少例子,在persistence.xml文件中也配置了二级缓存提供商,需要用到缓存的实体类和集合属性中也用注解的方式配置了@Cache(usage=CacheConcurrencyStrategy.READ_WRITE).
查询时:类中的集合属性可以运用到缓存,只显示一条SQL,但要查找某个类时,如:List<User> findAllUsers(),却无法
运用缓存,查一次就输出一句SQL语句.
求高手看看到底什么原因?

解决方案 »

  1.   

    呵呵, 给你贴一些我hibernate二级缓存的笔记...希望可以帮到你...比较忙, 你自己看看, jpa和hibernate差不多....1.1 二级缓存: 只缓存实体对象, 又称为进程级的缓存. 在整个进程(JVM)中是有效的. 可以被所有的session共享. 生命周期和sessionFactory的生命周期是一致的. sessionFactory可以管理二级缓存
    1.1.1.1 将ehcache.xml拷贝到src下.
    1.1.1.2 ehcache.xml的配置
    1.1.1.2.1 <diskStore path=”java.io.tmpdir” /> 配置一个磁盘路径
    1.1.1.2.1.1 path=java.io.tmdir  默认的临时文件路径, 如果是linux, 就是/tmp
    1.1.1.2.1.2 还可以配置成为一个具体的磁盘路径如C:\WINDOWS\TMP
    1.1.1.2.2 <defaultCache />配置
    1.1.1.2.2.1 maxElementsInMemory=”10000” 内存中最大缓存的对象数量
    1.1.1.2.2.2 eternal=”true/false” 缓存中的对象的生命周期是否是永远保持, 也就是说直到进行消亡.
    1.1.1.2.2.3 timeToIdleSeconds=”300” 缓存中的对象空闲等待时间
    1.1.1.2.2.4 timeToLiveSeconds=”600” 缓存中的对象的生命周期, 和timeToIdleSeconds结合使用, 对象在存在时间达到生命周期后, 如果空闲时间也达到了timeToIdleSeconds的话, 就将对象从缓存中清除.
    1.1.1.2.2.5 overflowToDisk=”true/false” 在内存中缓存的对象达到最大数量时, 是否将对象缓存到前面指定的硬盘上.
    1.1.1.2.3 <cache />配置其他缓存
    1.1.1.2.3.1 使用name配置缓存的名字, 其他配置和defaultCache是一致的.
    1.1.1.3 开启hibernate的二级缓存, 默认是开启的. session-factory配置中加入<property name="hibernate.cache.use_second_level_cache">true</property>
    1.1.1.4 指定缓存产品提供商: 在session-factory配置中加入配置: <property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property>  具体的cache提供商的类名在hibernate官方文档中有.
    1.1.1.5 ehcache不支持分布式的缓存. 
    1.1.1.6 热备: 其中一台服务器断了之后, 切换到另外一台服务器, 但是不会复制session, 用户需要重新登录. 
    1.1.1.7 重要的系统需要采用集群, 集群会对session进行复制, 这个会话的复制是分布式缓存来完成的.
    1.1.1.8 缓存策略(usage):  通过在要使用二级缓存的类的映射中, 在id标签之前, 使用<cache usage=”read-only” />指定缓存策略.   也可以在session-factory的配置中通过<class-cache class=”selfimpr.hibernate.model.Student” usage=”read-only” />的方式配置二级缓存…….推荐使用session-factory中配置, 较好管理.
    1.1.1.8.1 read-only: 只能从缓存中读数据, 发生的修改不会放到缓存中.  首选…..为了保证数据的一致性, 需要配置合理的缓存的生命周期.
    1.1.1.8.2 read-write: 对数据的修改也会放到缓存中.
    1.1.1.9 设置了二级缓存之后, 一级缓存clear之后, 也不会发出sql…..但是, 一级缓存还是有效的, 也就是说, 如果清理了二级缓存, 但是一级缓存中还有数据, 还是不会和数据库发生交互.  并且, 是首先从一级缓存中读取.
    1.1.1.10 CacheMode参数用于控制具体的Session如何与二级缓存进行交互…..默认是CacheModel.NORMAL   通过session.setCacheMode接口设置
    1.1.1.10.1 CacheMode.NORMAL  从二级缓存中读, 写数据.
    1.1.1.10.2 CacheMode.GET  从二级缓存中读取数据, 仅在数据更新时对二级缓存写数据.
    1.1.1.10.3 CacheMode.PUT 仅向二级缓存写数据, 但不从二级缓存中读数据.通过hibernate.cache.use_mimal_puts的设置, 强制二级缓存从数据库中读取数据, 刷新缓存内容.
      

  2.   

    谢谢LS的资料,我用JPA可以运用缓存,只是相对于某个实体类中的集合属性而言,但就像我标题所说,具体到某个实体时,却运用不到,我在要缓存的实体类中都加了注解@Cache(usage=CacheConcurrencyStrategy.READ_WRITE),但还是达不到效果,这是我的单元配置文件,是不是哪里有错误:<?xml version="1.0" encoding="UTF-8"?>
    <persistence xmlns="http://java.sun.com/xml/ns/persistence"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
        http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0">
        
    <persistence-unit name="library" transaction-type="RESOURCE_LOCAL">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
       <properties>
    <property name = "hibernate.connection.driver_class" value = "com.microsoft.sqlserver.jdbc.SQLServerDriver"/>
    <property name = "hibernate.connection.url" value = "jdbc:sqlserver://localhost:1433;databaseName=mylibrary"/>
    <property name = "hibernate.connection.username" value = "sa"/>
    <property name = "hibernate.connection.password" value = "sa"/>
    <property name = "hibernate.hbm2ddl.auto" value = "update"/>
    <property name="hibernate.show_sql" value="true"/>
    <!-- 设置II级缓存供应商 -->
    <property name="hibernate.cache.provider_class" value="org.hibernate.cache.EhCacheProvider" />
    <property name="hibernate.cache.use_query_cache" value="true"/>
    <property name="hibernate.cache.use_second_level_cache" value="true"/>
    <property name="hibernate.cache.use_structured_entries" value="true"/>
       </properties>
    </persistence-unit>
      
    </persistence>
      

  3.   

    JPA 1.0 的版本中没有缓存,@Cache 是 Hibernate 的 JPA 实现独有的,如果使用的话 JPA 就将依赖于 Hibernate