3

我已经开始使用带有二级缓存的 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 ​​次,不幸的是我看到休眠运行它 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 ​​次?我错过了一些配置吗?

在此先感谢,迈克尔

4

2 回答 2

5

javax.persistence.Query 中没有 setCacheable 方法,因此您需要将缓存提示添加到命名查询(或调用 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 Caching 抽象。

于 2012-07-22T16:14:15.360 回答
1

您的配置中不应该还有以下内容:

<cache usage="read-write"/>

另外我忘记了您需要cacheable="true"在命名查询上或 setCacheable(true)在运行查询本身时设置属性。

PS:不确定休眠中的语法是什么,但在休眠中它的 SetCacheable(true)

于 2012-07-22T15:38:34.533 回答