当前位置: 首页 > 知识库问答 >
问题:

Hibernate 4和二级缓存:我的理解有什么错?

胡玉书
2023-03-14

我已经开始使用Hibernate 4和二级缓存。根据文档,配置非常简单:

<property name="hibernate.cache.use_second_level_cache"  value="true"></property>
<property name="hibernate.cache.use_query_cache"  value="true"></property>
<property name="hibernate.cache.region.factory_class"  value="org.hibernate.cache.ehcache.EhCacheRegionFactory"></property>

根据我的理解,二级缓存应该消除对数据库的相同查询。我有非常简单的实体和非常简单的命名查询:

@Entity
@NamedQueries({
        @NamedQuery(name="SimplePerson.findByName", query="select p from SimplePerson p where p.name = :name"),
})

@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class SimplePerson {

    public static final String FIND_BY_NAME = "SimplePerson.findByName";

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int id;

    private String name;

    public SimplePerson() {

    }

    public SimplePerson(String name) {
        this.name = name;
    }



}

我运行了4次命名查询,不幸的是我看到hibernate运行了4次。

EntityManagerFactory emf = Persistence.createEntityManagerFactory("test");      
EntityManager em = emf.createEntityManager();

Query query = em.createNamedQuery(SimplePerson.FIND_BY_NAME);
query.setParameter("name", "BOB");

List result = query.getResultList();
result = query.getResultList();
result = query.getResultList();
result = query.getResultList();

输出:

Hibernate: select simplepers0_.id as id0_, simplepers0_.name as name0_ from SimplePerson simplepers0_ where simplepers0_.name=?
Hibernate: select simplepers0_.id as id0_, simplepers0_.name as name0_ from SimplePerson simplepers0_ where simplepers0_.name=?
Hibernate: select simplepers0_.id as id0_, simplepers0_.name as name0_ from SimplePerson simplepers0_ where simplepers0_.name=?
Hibernate: select simplepers0_.id as id0_, simplepers0_.name as name0_ from SimplePerson simplepers0_ where simplepers0_.name=?

我对二级缓存的理解有什么错?为什么Hibernate会运行查询4次?我是否错过了一些配置?

先谢谢你迈克尔

共有2个答案

裴兴言
2023-03-14

您的配置中不也应该包含以下内容:

<cache usage="read-write"/>

此外,我忘了在运行查询本身时,您需要在命名查询上设置属性,或者设置可缓存属性(true)。

P、 S:不确定hibernate中的语法是什么,但在Nhibernate中它是可设置缓存的(true)

沈永贞
2023-03-14

setCacheable方法在javax.persistence.Query中不可用,因此您需要将缓存提示添加到命名查询(或调用setHint):

@NamedQueries({
@NamedQuery(
    name="SimplePerson.findByName", 
    query="select p from SimplePerson p where p.name = :name", 
    hints = { @QueryHint(name = "org.hibernate.cacheable", value = "true") })
})

也就是说,使用查询缓存已经跳过鲨鱼,如果您打算考虑它,下面的文章是必须阅读的。如今有更好的方法,例如Spring缓存抽象。

 类似资料:
  • 本文向大家介绍深入理解Mybatis二级缓存,包括了深入理解Mybatis二级缓存的使用技巧和注意事项,需要的朋友参考一下 上篇文章给大家介绍了mybatis一级缓存,有需要的朋友可以参考下。 与一级缓存相比,二级缓存范围更大了一些,可以被多个SqlSession所共用。 同样是发送同样的查询sql会先去缓存中找,找不到再去查询数据库。 每个namespace的mapper都会有自己的一个缓存的空

  • 问题内容: 谁能用简单的语言解释一下Hibernate中的一级和二级缓存是什么? 问题答案: 1.1)一级缓存 一级缓存 始终与 Session对象 关联。Hibernate默认使用此缓存。在这里,它处理一个事务接一个另一个事务,意味着不会多次处理一个事务。主要是它减少了在给定事务中需要生成的SQL查询的数量。那不是在事务中完成每次修改之后更新,而是仅在事务结束时更新事务。 1.2)二级缓存 二级

  • 当你使用本地(在内存中)缓存时,服务器可以缓存一些信息并快速地检索它,但是其他服务器不能访问这个缓存数据,他们需要到数据库中查询同样的信息。 如果你喜欢使用分布式缓存让其他服务器访问缓存的数据,由于它有一些序列化/反序列化和网络延迟开销,则需要注意:在某些情况下,它可能会降低性能。 缓存需要处理的另一个问题:缓存失效。 There are only two hard things in Compu

  • 本文向大家介绍说一下 MyBatis 的一级缓存和二级缓存?相关面试题,主要包含被问及说一下 MyBatis 的一级缓存和二级缓存?时的应答技巧和注意事项,需要的朋友参考一下 一级缓存:基于 PerpetualCache 的 HashMap 本地缓存,它的声明周期是和 SQLSession 一致的,有多个 SQLSession 或者分布式的环境中数据库操作,可能会出现脏数据。当 Session f

  • 1、一级缓存:指的是mybatis中sqlSession对象的缓存,当我们执行查询以后,查询的结果会同时存入sqlSession中,再次查询的时候,先去sqlSession中查询,有的话直接拿出,当sqlSession消失时,mybatis的一级缓存也就消失了,当调用sqlSession的修改、添加、删除、commit()、close()等方法时,会清空一级缓存。 2、二级缓存:指的是mybati

  • 一级缓存是session级别的缓存,默认开启,当查询一次数据库时,对查询结果进行缓存,如果之后的查询在一级缓存中存在,则无需再访问数据库; 二级缓存是sessionFactory级别的缓存,需要配置才会开启。当进行sql语句查询时,先查看一级缓存,如果不存在,访问二级缓存,降低数据库访问压力。